关于原型陷阱的一个总结

版权声明:内容多为自言自语,请自行判断有无价值。 https://blog.csdn.net/weixin_41702247/article/details/83450002
function Person(name){
    this.name=name
}
Person.prototype.sayName=function(){
    console.log(this.name);
}

var person1=new Person('tom');
person1.sayName();  //tom
Person.prototype.constructor===Person;  //true

Person.prototype={
    age:21,
    greet:function(){
        console.log(`Hello, I'm ${age} years old.`);
    }
}
//Person.prototype.constructor=Person;

person1.sayName();  //tom
person1.age;    //undefined
person1.greet();    //TypeError: person1.greet is not a function


var person2=new Person('mary');
person2.age;    //21
person2.sayName();  //TypeError: person2.sayName is not a function

// 以上解决的是重定义原型对象时导致的实例指向问题


// 以下是原型上的constructor属性指向错误问题,此问题虽然不影响实际操作,但会导致无法通过constructor确定对象类型
Person.prototype.constructor===Person;  //false
Object.getPrototypeOf(Person);  //ƒ Object() { [native code] }          Object构造函数
person1.constructor===Person;   //true
person2.constructor===Person;   //false

//正确做法是在上方重定义原型之后,就直接对其进行纠正
//亦可在重定义的原型内部对constructor属性进行赋值,但如此会导致其enumerable属性为true
//原生默认是false,虽然目前没发现有什么其他影响,但最好不要修改原生属性的描述符
//因此最好的办法就是在外部声明
Person.prototype.constructor=Person;
person2.constructor===Person;   //true

问题描述:

使用对象字面量方法重新定义对象原型或令其指向现有的自定义对象时,出现的constructor指向问题,和,旧对象仍能访问旧原型但无法访问新原型属性的情况

原因:

constructor属性仅属于原型对象,实例化的对象可以通过__proto__链接进行访问,但此链接仅指向原型对象,而不指向构造函数(高程是这么翻译的,但我觉得不容易理解。看后续配图的意思其实是,__proto__链接默认指向实例被定义时的原型对象,但如果人为的重定义原型对象,其实等同于新建一个对象。因此旧的实例在原型对象被重定义后仍能访问旧原型上的属性,但此时如果新实例化一个对象,则一切正常)

解决办法:

在重定义原型对象后,直接对其constructor属性进行人为的重新绑定。

(仅从避免原型陷阱方面考虑,如果加入继承因素,还有别的方法可以避免,后面再总结)

我不知道多少人会看这个总结,首先我自己是新手,对原型陷阱从第一次看到这个概念查资料完全不知道干嘛的到现在能捋顺大致经过了两次顿悟,第一次是经过看多本讲js的书之后,弄明白跟函数和原型相关的所有概念,但各本书看的说法都不很一致,那个时候没形成体系,知识是散的;第二次是现在再看高程,把原先零散的知识串了起来,这种感觉还是很开心的。

虽然透彻理解这个问题对于js并不一定会有实质性的进步,但量变终会引起质变,我相信所有在编程方面的高手,除了少数的天才一看就明白之外,一定更多的人是一点点积累同时思考进步的。

如果看到的人能看明白我整个思路,那说明我们都理解了这个问题。

如果看不懂,也不用灰心,总结起来就那么十几行代码,但明白为什么那样验证,这个思路和严谨的论证过程是需要很多其他方面知识铺垫的。

最后,如果此文有错误还请指正。当然,后续我自己实际使用时发现有错误我也会回来纠正。

愿所有没人指点的自学者都可以熬到云开现月的时刻,不要半途而废。

猜你喜欢

转载自blog.csdn.net/weixin_41702247/article/details/83450002