==================
原型与继承关系检测
构造函数的pototype是否出现在某个实例对象的原型链上
console.log(instance instanceof Object); // true
console.log(instance instanceof a); // true
console.log(instance instanceof b); // true
console.log(Object.prototype.isPrototypeOf(instance)); // true
console.log(a.prototype.isPrototypeOf(instance)); // true
console.log(b.prototype.isPrototypeOf(instance)); // true
对象属于某个原型 isPrototypeOf
console.log(Person.prototype.isPrototypeOf(person1)); // true
console.log(Person.prototype.isPrototypeOf(person2)); // true
有无自己的属性hasOwnProperty
判断哪个属性,是它自己的,还是原型上的
有没有原型的属性 hasPrototypeProperty
测试看实例上有没有原型继承下来的属性,被实例属性屏蔽就会返回false
let person = new Person();
console.log(hasPrototypeProperty(person, "name")); // true
person.name = "Greg";
console.log(hasPrototypeProperty(person, "name")); // false
有没有属性 in
只要有这个属性,不管是实例自己的,还是原型上的,都返回true
console.log("name" in person1); // true
// 确定某个属性是否存在于原型上
function hasPrototypeProperty(object, name){
return !object.hasOwnProperty(name) && (name in object);
}
==================
迭代(遍历)
枚举实例自身所有属性 Object.getOwnPropertyNames()
包括不枚举的属性constructor,不包括Symbol属性
Object.getOwnPropertySymbols( )方法可以枚举出Symbols属性
let keys = Object.getOwnPropertyNames(Person.prototype);
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 循环中返回,因为默认情况下开发者定义的属性都是可枚举的
function Person() {}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function() {
console.log(this.name);
};
let p1 = new Person();
for (let item in p1) {
console.log(item);
}//name age job sayName
Object.keys( ) 枚举实例自身属性
p1.age = 31;
let p1keys = Object.keys(p1);
console.log(p1keys); // "[age]"
==================
修改原型
Object.setPrototypeOf( )
修改某个对象的原型,但不推荐,因为可能会严重影响代码性能,
let biped = {
numLegs: 2
};
let person = {
name: 'Matt'
};
Object.setPrototypeOf(person, biped);
console.log(person.name); // Matt
console.log(person.numLegs); // 2
console.log(Object.getPrototypeOf(person) === biped); // true
替代方案:可以通过 Object.create()来创建一个新对象,同时为其指定原型
let biped = {
numLegs: 2
};
let person = Object.create(biped);
person.name = 'Matt';
console.log(person.name); // Matt
console.log(person.numLegs); // 2
console.log(Object.getPrototypeOf(person) === biped); // true