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属性进行人为的重新绑定。
(仅从避免原型陷阱方面考虑,如果加入继承因素,还有别的方法可以避免,后面再总结)