Crockford 的原型继承:嵌套对象的问题
Douglas Crockford 的原型继承模式,在他的书《Javascript:The Good Parts》中概述,简化了对象继承并避免了与“new”关键字相关的混乱。但是,当尝试使用此模式从嵌套对象继承时,会出现一个问题:覆盖嵌套对象属性会影响整个原型链。
考虑以下代码:
var flatObj = { firstname: "John", lastname: "Doe", age: 23 } var person1 = Object.create(flatObj); var nestObj = { sex: "female", info: { firstname: "Jane", lastname: "Dough", age: 32 } } var person2 = Object.create(nestObj); var nestObj2 = { sex: "male", info: { firstname: "Arnold", lastname: "Schwarzenneger", age: 61 } } var person3 = { sex: "male" } person3.info = Object.create(nestObj2.info); // now change the objects: person1.age = 69; person2.info.age = 96; person3.info.age = 0; // prototypes should not have changed: flatObj.age // 23 nestObj.info.age // 96 ??? nestObj2.info.age // 61 // now delete properties: delete person1.age; delete person2.info.age; delete person3.info.age; // prototypes should not have changed: flatObj.age // 23 nestObj.info.age // undefined ??? nestObj2.info.age // 61
在此例如,从嵌套对象nestObj继承后,更改person2中嵌套对象的属性会影响原型nestObj,对于person3的嵌套对象也是如此。这是意想不到的行为,破坏了模式隔离单个对象更改的预期目的。
这种不一致的原因在于 JavaScript 对象继承的基本性质。当一个对象从另一个对象继承时,它会创建对该对象属性的引用,而不是创建独立的副本。这意味着对继承属性所做的任何更改都会反映在子对象和原型中。
为了避免此问题,必须在继承嵌套属性之前显式地为嵌套属性创建一个新对象。这可确保对嵌套属性的更改与子对象隔离。因此,正确的代码应该是:
person3.info = Object.create(nestObj2.info); // Create a new object for the nested property person3.info.age = 0; // Change the age property without affecting the prototype
以上是Crockford 的原型继承如何处理嵌套对象和属性修改?的详细内容。更多信息请关注PHP中文网其他相关文章!