1nf*_*iti 13 javascript prototypal-inheritance
我一直在阅读道格拉斯·克罗克福德的"Javascript:The Good Parts" - 虽然它有点极端,但我已经接受了很多他要说的话.
在第3章中,他讨论了对象,并且在某一点上列出了一种模式(也在这里找到),用于简化和避免使用内置"new"关键字时出现的一些混淆/问题.
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
newObject = Object.create(oldObject);
Run Code Online (Sandbox Code Playgroud)
所以我尝试在我正在处理的项目中使用它,并且在尝试从嵌套的对象继承时发现了一个问题.如果我覆盖使用此模式继承的嵌套对象的值,它将覆盖原型链上的嵌套元素.
Crockford的例子就像flatObj下面的例子一样,效果很好.但是,该行为与嵌套对象不一致:
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
Run Code Online (Sandbox Code Playgroud)
(也是小提琴)
我做错了什么,或者这是这种模式的限制?
Ber*_*rgi 11
没有不一致.只是不要考虑嵌套对象:对象的直接属性总是在其原型或自己的属性上.与属性或对象的属性值无关.
所以,当你这样做的时候
var parent = {
x: {a:0}
};
var child = Object.create(parent);
Run Code Online (Sandbox Code Playgroud)
child.x将引用相同的对象parent.x-一个{a:0}对象.当你改变它的属性时:
var prop_val = child.x; // == parent.x
prop_val.a = 1;
Run Code Online (Sandbox Code Playgroud)
两者都会受到影响.要独立更改"嵌套"属性,首先必须创建一个独立对象:
child.x = {a:0};
child.x.a = 1;
parent.x.a; // still 0
Run Code Online (Sandbox Code Playgroud)
你能做的是
child.x = Object.create(parent.x);
child.x.a = 1;
delete child.x.a; // (child.x).a == 0, because child.x inherits from parent.x
delete child.x; // (child).x.a == 0, because child inherits from parent
Run Code Online (Sandbox Code Playgroud)
这意味着它们并非绝对独立 - 但仍然是两个不同的对象.