==================

原型与继承关系检测

构造函数的pototype是否出现在某个实例对象的原型链上

  1. console.log(instance instanceof Object); // true
  2. console.log(instance instanceof a); // true
  3. console.log(instance instanceof b); // true
  4. console.log(Object.prototype.isPrototypeOf(instance)); // true
  5. console.log(a.prototype.isPrototypeOf(instance)); // true
  6. console.log(b.prototype.isPrototypeOf(instance)); // true

对象属于某个原型 isPrototypeOf

  1. console.log(Person.prototype.isPrototypeOf(person1)); // true
  2. console.log(Person.prototype.isPrototypeOf(person2)); // true

有无自己的属性hasOwnProperty

判断哪个属性,是它自己的,还是原型上的
image.png

有没有原型的属性 hasPrototypeProperty

测试看实例上有没有原型继承下来的属性,被实例属性屏蔽就会返回false

  1. let person = new Person();
  2. console.log(hasPrototypeProperty(person, "name")); // true
  3. person.name = "Greg";
  4. console.log(hasPrototypeProperty(person, "name")); // false

有没有属性 in

只要有这个属性,不管是实例自己的,还是原型上的,都返回true

  1. console.log("name" in person1); // true
  2. // 确定某个属性是否存在于原型上
  3. function hasPrototypeProperty(object, name){
  4. return !object.hasOwnProperty(name) && (name in object);
  5. }

==================

迭代(遍历)

枚举实例自身所有属性 Object.getOwnPropertyNames()

包括不枚举的属性constructor,不包括Symbol属性
Object.getOwnPropertySymbols( )方法可以枚举出Symbols属性

  1. let keys = Object.getOwnPropertyNames(Person.prototype);
  2. console.log(keys); // "[constructor,name,age,job,sayName]"

属性枚举顺序

for-in 循环和 Object.keys()的枚举顺序是不确定的,取决于 JavaScript 引擎,可能因浏览器而异;

Object.getOwnPropertyNames()、Object.getOwnPropertySymbols()和 Object.assign()的枚举顺序是确定性的。
先以升序枚举数值键,然后以插入顺序枚举字符串和符号键。

在对象字面量中定义的键以它们逗号分隔的顺序插入。

for in 循环枚举实例所有属性

在 for-in 循环中使用 in 操作符时,可以通过对象访问且可以被枚举的属性都会返回,包括实例属性和原型属性。

遮蔽原型中不可枚举([[Enumerable]]特性被设置为 false)属性的实例属性也会在 for-in 循环中返回,因为默认情况下开发者定义的属性都是可枚举的

  1. function Person() {}
  2. Person.prototype.name = "Nicholas";
  3. Person.prototype.age = 29;
  4. Person.prototype.job = "Software Engineer";
  5. Person.prototype.sayName = function() {
  6. console.log(this.name);
  7. };
  8. let p1 = new Person();
  9. for (let item in p1) {
  10. console.log(item);
  11. }//name age job sayName

Object.keys( ) 枚举实例自身属性

  1. p1.age = 31;
  2. let p1keys = Object.keys(p1);
  3. console.log(p1keys); // "[age]"

==================

修改原型

Object.setPrototypeOf( )
修改某个对象的原型,但不推荐,因为可能会严重影响代码性能,

  1. let biped = {
  2. numLegs: 2
  3. };
  4. let person = {
  5. name: 'Matt'
  6. };
  7. Object.setPrototypeOf(person, biped);
  8. console.log(person.name); // Matt
  9. console.log(person.numLegs); // 2
  10. console.log(Object.getPrototypeOf(person) === biped); // true

替代方案:可以通过 Object.create()来创建一个新对象,同时为其指定原型

  1. let biped = {
  2. numLegs: 2
  3. };
  4. let person = Object.create(biped);
  5. person.name = 'Matt';
  6. console.log(person.name); // Matt
  7. console.log(person.numLegs); // 2
  8. console.log(Object.getPrototypeOf(person) === biped); // true