一尘不染

JavaScript Crockford的原型继承-嵌套对象的问题

javascript

我一直在阅读道格拉斯·克罗克福德(DouglasCrockford)撰写的“Javascript:好的部分”,尽管有些极端,但我同意他的许多意见。

在第3章中,他讨论了对象,并在某一时刻列出了一种模式,以简化和避免使用内置的“
new”关键字带来的一些混淆/问题。

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}
newObject = Object.create(oldObject);

因此,我尝试在正在处理的项目中使用它,并且在尝试从嵌套对象继承时发现了一个问题。如果我覆盖使用此模式继承的嵌套对象的值,则它将覆盖原型链中的嵌套元素。

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

我是在做错什么,还是这是这种模式的局限性?


阅读 309

收藏
2020-04-25

共1个答案

一尘不染

没有矛盾。只是不要考虑嵌套对象:对象的直接属性总是在其原型上或在自己的属性上。属性值是否为基元或对象与无关紧要。

所以,当你这样做

var parent = {
    x: {a:0}
};
var child = Object.create(parent);

child.x将引用与parent.x-一个{a:0}对象相同的对象。当您更改其属性时:

var prop_val = child.x; // == parent.x
prop_val.a = 1;

两者都会受到影响。要独立更改“嵌套”属性,您首先必须创建一个独立的对象:

child.x = {a:0};
child.x.a = 1;
parent.x.a; // still 0

你能做的是

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

which means they are not absolutely independent - but still two different
objects.

2020-04-25