新函数创建时都会有一个prototype
属性(指针)指向其原型
原型的constructor
则是指向该函数
obj.prototype.constructor;
//ƒ obj(){}
新函数可以作为一个构造函数new一个实例
var o = new obj();
o.__proto__;
这里的__proto__
实则是实例的内部属性[[protopyte]]
,指向的是函数的原型。
也就是说构造函数的prototype属性与相应实例的[[prototype]]指向同一个原型对象。
而实例的constructor
属性则是和原型的constructor
相同,指向同一个函数。
o.constructor === o.__proto__.constructor;
//true
因此在以如下方式构造原型链时,
function SuperType(){
this.prop = "super";
}
function SubType(){
this.subprop = "sub"
}
SubType.prototype = new SuperType();
var instance = new SubType();
console.log(instance.constructor);
//function SuperType()
因为SubType.prototype
被重写了,所以instance.__proto__
也变成了SuperType()
的实例,所以
instance.constructor ===
(new SuperType()).constructor ===
(new SuperType()).__proto__.constructor
//最后推出便是SuperType()
所以当使用
SubType.prototype = new SuperType();
来构造原型链时,要找实例的constructor,只需记住一行代码——
o.constructor === o.__proto__.constructor;
补充:
o.constructor === o.__proto__.constructor;
因为自定义构造函数new出来的实例并没有constructor
属性,所以访问obj的constructor
属性时,要沿着原型链往上找,于是找到的是原型的constructor
属性。
function fun(){};
let ob = new fun();
fun.constructor; //Function()
fun.prototype; //{constructor: ƒ fun()}
ob.constructor; //f fun(){}
ob.__proto__; //{constructor: ƒ fun()}
fun.prototype.constructor; //f fun(){}
感谢阅读!