例子:
function monkey(){}
function human(){}
function developer(){}
human.prototype=new monkey();
developer.prototype=new human();
human.prototype.constructor=human;
developer.prototype.constructor=developer;
今天看到上面的例子中developer.prototype.constructor=developer;的时候,发现很奇怪,我一直以为developer的prototype指向的是human,那human的constructor按道理应该指向new了他的构造函数,那不应该指向monkey吗?
//因为js中constructor 属性指向创建它的构造函数
//例如
function monkey(){
this.name="monkey"
}
var monkey1=new monkey();
monkey1.constructor===monkey;//true
越想越纳闷,后来才发现是我理解prototype时理解错了;
在打印控制台打印,越来越复杂__proto__和prototype,constructor又是什么关系?
developer1.__proto__===developer.prototype;
//true
developer1.__proto__.__proto__===human.prototype;
//true
developer1.__proto__.__proto__.__proto__===monkey.prototype;
//true
developer.__proto__==human.prototype;
//true
developer.prototype.__proto__==human.prototype;
//true
human.prototype=new monkey();
//其中new monkey()覆盖了human的prototype属性,使得该属性原有的constructor消失,所以要手动重置constructor属性
human.prototype.constructor=human;
总结就是
实例化的对象的_proto_指向构造函数的prototype
构造函数有prototype属性,该属性(对象)还有两个属性,constructor属性指向自己,_proto_属性指向父元素的prototype
理解原型链的过程还可以顺带回答面试经常问的问题
new的过程中发生了什么?
1.创建一个新的对象,
2.该对象的_proto_指向构造函数的prototype,实现继承
3.执行构造函数,当有this关键字时,使用新创建的对象属性
4.创建对象成功后,如果访问该对象没有的属性,则会按照原型链一层一层查找。
MDN是这样说的:
当代码 new
Foo
(...)
执行时,会发生以下事情:
- 一个继承自
Foo
.prototype
的新对象被创建。 - 使用指定的参数调用构造函数
Foo
,并将this
绑定到新创建的对象。new Foo
等同于new
Foo
()
,也就是没有指定参数列表,Foo
不带任何参数调用的情况。 - 由构造函数返回的对象就是
new
表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤1创建的对象。(一般情况下,构造函数不返回值,但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤)