Crockford的Prototypal继承 - 嵌套对象的问题 [英] Crockford's Prototypal inheritance - Issues with nested objects

查看:106
本文介绍了Crockford的Prototypal继承 - 嵌套对象的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读道格拉斯·克罗克福德的Javascript:The Good Parts - 虽然它有点极端,但我已经接受了很多他要说的话。

I've been reading "Javascript: The Good Parts" by Douglas Crockford - and while it's a bit extreme, I'm on board with a lot of what he has to say.

在第3章中,他讨论了对象,并在某一点上列出了一种模式(同样在这里找到)以简化&避免使用内置new关键字时出现的一些混淆/问题。

In chapter 3, he discusses objects and at one point lays out a pattern (also found here) for simplifying & avoiding some of the confusion/issues that come with the use of the built-in "new" keyword.

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

所以我尝试在我正在进行的项目中使用它,我发现了一个问题尝试从嵌套的对象继承时。如果我覆盖使用此模式继承的嵌套对象的值,它会覆盖原型链中的嵌套元素。

So I've tried using this in a project I'm working on, and I noticed an issue when attempting to inherit from objects that are nested. If I overwrite a value of a nested object inherited using this pattern, it overwrites the nested element all the way up the prototype chain.

Crockford的示例就像 flatObj 在以下示例中,效果很好。但是,该行为与嵌套对象不一致:

Crockford's example is like the flatObj in the following example, which works well. The behaviour, however, is inconsistent with nested objects:

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

(也在小提琴

我做错了什么,或者这是一个限制这种模式?

Am I doing something wrong, or is this a limitation of this pattern?

推荐答案

没有不一致之处。只是不要考虑嵌套对象:对象的直接属性总是在其原型或自己的属性上。这个属性值与原始值或对象无关。

There is no inconsistency. Just don't think of nested objects: a direct property of an object is always either on its prototype or an own property. It's irrelevant wheter the property value a primitive or an object.

所以,当你这样做时

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

child.x 将引用相同的内容object as parent.x - 那个 {a:0} 对象。当你改变它的属性时:

child.x will be referencing the same object as parent.x - that one {a:0} object. And when you change a property of it:

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

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

both will be affected. To change a "nested" property independently, you first will have to create an independent object:

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.

这篇关于Crockford的Prototypal继承 - 嵌套对象的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆