# property 与遍历

# isPrototypeOf()

isPrototypeOf()方法用于测试一个对象是否存在于另一个对象的原型链上。

function foo() {}
var foo1 = new foo();
foo.prototype.isPrototypeOf(foo1); // true
var obj = {};
foo1.__proto__ = obj;
obj.isPrototypeOf(foo1); // true

# instanceof

instanceof 运算符用于检测构造函数的  prototype属性是否出现在某个实例对象的原型链上。

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);

console.log(auto instanceof Car);
// expected output: true

console.log(auto instanceof Object);
// expected output: true

# hasOwnProperty()

hasOwnProperty():方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。

const object1 = {};
object1.property1 = 42;

console.log(object1.hasOwnProperty('property1'));
// expected output: true

console.log(object1.hasOwnProperty('toString'));
// expected output: false

console.log(object1.hasOwnProperty('hasOwnProperty'));
// expected output: false

# Object.getOwnPropertyNames()

Object.getOwnPropertyNames():方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括 Symbol 值作为名称的属性)组成的数组。

var arr = ['a', 'b', 'c'];
console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]
// 类数组对象
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]
//不可枚举属性
var my_obj = Object.create(
  {},
  {
    getFoo: {
      value: function() {
        return this.foo;
      },
      enumerable: false
    }
  }
);
my_obj.foo = 1;
console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]

# Object.getPrototypeOf

Object.getPrototypeOf:方法返回指定对象的原型(内部[[Prototype]]属性的值)

const prototype1 = {};
const object1 = Object.create(prototype1);

console.log(Object.getPrototypeOf(object1) === prototype1);
// expected output: true

# Object.keys()

Object.keys():方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。

# Object.defineProperty()

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

# 语法

Object.defineProperty(obj, prop, descriptor);
  • obj:要定义属性的对象。
  • prop:要定义或修改的属性的名称或 Symbol 。
  • descriptor:要定义或修改的属性描述符。
    • configurable:当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false
    • enumerable:当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。默认为 false
    • value:该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined
    • writable: 当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变。默认为 false
    • get:属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的 this 并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。默认为 undefined
    • set:属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。默认为 undefined

tips:
拥有布尔值的键 configurable、enumerable 和 writable 的默认值都是 false。
属性值和函数的键 value、get 和 set 字段的默认值为 undefined。

# for 循环

var list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (let i = 0; i < list.length; i++) {
  if (i < 3) {
    continue;
  }
  if (i > 7) {
    break;
  }
  console.log(list[i]); // 4,5,6,7,8
}
console.log(list.length); // 10

# for...in

  • for...in :以任意顺序遍历一个对象的除 Symbol 以外的可枚举属性。包括对象的原型属性也会被遍历。可以用hasOwnProperty()来过滤。它遍历返回的是属性 key 而不是属性的值value
  • for ... in 是为遍历对象属性而构建的,不建议与数组一起使用,数组可以用Array.prototype.forEach()for ... of
  • for...in 不应该用于迭代一个关注索引顺序的  Array。

# for...of

for...of:语句遍历可迭代对象定义要迭代的数据。不包括原型上的属性。不以是否可枚举来遍历,以迭代器要迭代的数据来遍历。

Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = 'hello';

for (let i in iterable) {
  console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); // logs 0, 1, 2, "foo"
  }
}

for (let i of iterable) {
  console.log(i); // logs 3, 5, 7
}
// Object.getOwnPropertyDescriptors(iterable)
//
// 0: {value: 3, writable: true, enumerable: true, configurable: true}
// 1: {value: 5, writable: true, enumerable: true, configurable: true}
// 2: {value: 7, writable: true, enumerable: true, configurable: true}
// foo: {value: "hello", writable: true, enumerable: true, configurable: true}
// length: {value: 3, writable: true, enumerable: false, configurable: false}