当创建了一个新函数,就会为这个函数创建一个prototype属性,这个属性指向函数的原型对象,原型对象会自动获得一个constructor属性,这个属性又指回函数。所以Person.prototype.constructor是指向Person的
1559101671711.png
原型对象默认只会获得constructor属性,其他属性、方法是从Object继承而来的。
1559102201960.png
当new一个实例后,该实例内部的属性指针 ' [[Prototype]] ' 就会指向原型对象,在所有实现中都无法访问到[[Prototype]],但可以通过Object.getPrototypeOf()返回它的值,返回的对象就是这个对象的原型
1559102493293.png
当我们访问person1.sayName()时,会先搜索实例person1有saName属性吗?没有就会继续搜索,person1的原型有sayName属性吗,有的话就会读取保存在原型对象里的函数
虽然可以读取保存在原型中的值,但是不能通过实例重写原型中的值,只会屏蔽,例如
function Person(){
}
Person.prototype.name = 'zzx';
Person.prototype.age = 22;
Person.prototype.job = 'Programmer';
Person.prototype.sayName = function(){
console.log(this.name);
}
var person1 = new Person();
var person2 = new Person();
person1.name = 'yzy';
console.log(person1.name); //'yzy'实例中的值
console.log(person2.name); //'zzx'原型中的值
即使将person1的name设置为null,也不会恢复指向原型的连接,但是可以使用delete操作符完全删除实例属性,从而重新访问原型中的属性
使用hasOwnProperty()方法可以检测一个属性是存在于实例还是存在于原型中,这个方法只有给定属性存在于对象实例中时才会返回true。
function Person(){
}
Person.prototype.name = 'zzx';
Person.prototype.age = 22;
Person.prototype.job = 'Programmer';
Person.prototype.sayName = function(){
console.log(this.name);
}
var person1 = new Person();
console.log(person1.hasOwnProperty('name')); //false
person1.name = 'yzy';
console.log(person1.hasOwnProperty('name')); //true
delete person1.name;
console.log(person1.hasOwnProperty('name')); //false
当设置person1.name=‘yzy'后:
1559113158551.png
有两种方式使用in操作符:单独使用和在for-in循环中使用。单独使用时,in操作符会在通过对象访问给定属性时返回true,无论该属性会存在于实例还是原型中。因此配合Object.getOwnProperty()使用就知道该属性是存在于对象中还是存在于原型中。
function hasPrototypeProperty(object, name){
return !object.hasOwnProperty(name) && (name in object);
}