每一个js对象(除了null)都有__proto__这个属性,这个属性会指向该对象的原型,
每个实例的__proto__属性都指向它构造函数的prototype,也正是因为建立起这样的关系,实例可以访问原型上的属性
那么原型的原型是什么呢?
我们知道原型是个对象,那么很容易想到,构造函数的原型的原型就是Object.prototype,即 Constructor.prototype.proto = Object.prototype,
那么Object.prototype的原型呢?
console.log(Object.prototype === null)//true
null就是没有,就是说Object.prototype没有原型,所以当我们实例化一个对象以后,查找它的属性,如果当前对象找不到该属性值,就会从构造函数的原型上找该属性,如果还没有就继续往上找,直到Object.prototype。
下面用代码来实践一下:
function Person() {
}
Person.prototype.name = 'Kevin';
Object.prototype.name = 'Kate'
var person = new Person();
person.name = 'Daisy';
console.log(person.name) // Daisy
delete person.name;
console.log(person.name) // Kevin
delete Person.prototype.name;
console.log(person.name);//Kate
Person这个构造函数实例化一个person,我们要想打印它的name属性,首先看person中有没有这个属性,有的话打印,没有的话就看Person中有没有,没有的话再继续往上找。
注意 这里的没有指的是不存在,而不是undefined
function A(x){
this.x = x;
}
A.prototype.x = 1;
function B(x){
this.x = x;
}
B.prototype = new A();
var a = new A(2), b = new B(3);
delete b.x;
是否以为输出结果是 2,1
其实答案是 2, undefined
因为B的原型为A的实例化函数 即
function A(x){
this.x = x;
}
由于没有传入x的值,所以x = undefined
即 B.prototype = {x:undefined},undefined也是意味着有值,所以不会去原型链再找,大家自行体会