理解原型

新函数创建时都会有一个prototype属性(指针)指向其原型

image
原型的constructor则是指向该函数

obj.prototype.constructor;
//ƒ obj(){}

新函数可以作为一个构造函数new一个实例

var o = new obj();
o.__proto__;

image
这里的__proto__实则是实例的内部属性[[protopyte]],指向的是函数的原型。
也就是说构造函数的prototype属性与相应实例的[[prototype]]指向同一个原型对象。
而实例的constructor属性则是和原型的constructor相同,指向同一个函数。

o.constructor === o.__proto__.constructor;
//true

image
因此在以如下方式构造原型链时,

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()

image
所以当使用

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(){}

感谢阅读!

posted @ 2021-04-19 10:45  叶际参差  阅读(53)  评论(0编辑  收藏  举报