关于原型陷阱的一个总结

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属性进行人为的重新绑定。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值