为了实现 NinjaTestInherit继承Person,产生了这样的问题:当把NinjaTestInherit的原型设置为Person的实例对象后,我们丢失了原来在constructor中的NinjaTestInherit原型。如果我们不希望丢失constructor属性,constructor属性可用于确定用于创建对象实例的函数。
使用Object.defineProperty方法在 NinjaTestInherit.property对象上增加新的constructor属性。
console.log('----------------------解决constructor属性的问题----------------------');
function Person() {}
Person.prototype.dance = function () {}
function NinjaTestInherit() {}
NinjaTestInherit.prototype = new Person();
//定义一个新的不可枚举的constructor属性,属性值是 NinjaTestInherit
Object.defineProperty(NinjaTestInherit.prototype, "constructor",{
enumerable: false,
value: NinjaTestInherit,
writable: true
});
var ninjaTestInherit = new NinjaTestInherit();
//建立的ninjaTestInherit的constructor与NinjaTestInherit的联系
if (ninjaTestInherit.constructor === NinjaTestInherit) {
console.log("Connection from ninjaTestInherit instances to NinjaTestInherit constructor reestablished!");
}
//在NinjaTestInherit.prototype上没有定义可枚举的属性
for(let prop in NinjaTestInherit.prototype) {
if (prop === 'dance') {
console.log("The only enumerable property is dance!");
}
}
通过上述代码重新建立了ninjaTestInherit实例与NinjaTestInherit构造器之间的联系,所以可以确定ninjaTestInherit实例是通过NinjaTestInherit构造器创建的。此外,如果遍历NinjaTestInherit.proptype对象,可确保不会访问到constructor属性。
参考《JavaScript忍者秘籍》