javascript:关于原型继承的一个令人困惑的观点

时间:2017-03-09 03:43:38

标签: inheritance prototype

我在我的项目中遇到了一个问题,它与JS的原型继承有关。并将主要问题抽象如下:

var parentObj = {
    value:"parent value",
    obj: {
        obj: "parent obj value"
    }
}

var childObj = Object.create(parentObj)

以文字对象的方式创建parentObj,并根据它创建childObj并将其作为原型。

在第一种情况下如下:

childObj.value ="child value"
childObj.obj = {obj:"child obj value"};
console.log(parentObj)
console.log(childObj)

输出是:

{ value: 'parent value', obj: { obj: 'parent obj value' } }
{ value: 'child value', obj: { obj: 'child obj value' } }

此结果符合预期。

但对于第二种情况如下:

childObj.value ="child value"
childObj.obj.obj = "child obj value";
console.log(parentObj);
console.log(childObj);

输出结果为:

{ value: 'parent value', obj: { obj: 'child obj value' } }
{ value: 'child value' }

parentObj已更改。这个结果对我来说有点混乱,有什么帮助吗?

1 个答案:

答案 0 :(得分:0)

当您使用x = Object.create(y)时,您会获得一个x作为其y属性的对象__proto__

__proto__允许在JS中进行属性委派。

属性委派意味着当您向对象询问属性时,如果该对象没有该属性,该对象将询问其父对象(__proto__)。如果父对象也没有它,那么它将询问它的父对象。

如果在链用尽之前找到该值,则返回该值,否则返回undefined

在你的情况下

var parentObj = {
    value:"parent value",
    obj: {
        obj: "parent obj value"
    }
}

var childObj = Object.create(parentObj)

parentObj__proto__

childObj
console.log(childObj.__proto__ === parentObj) // true

此外,childObj 拥有自己的名为.obj.value的属性。 您可以使用Object.getOwnPropertyNames进行检查。 这是确定对象上是否存在属性的唯一方法。

console.log(Object.getOwnPropertyNames(parentObj)) // ["value", "obj"]
console.log(Object.getOwnPropertyNames(childObj)) // []

执行childObj.obj.obj = ...后,您可以修改对象.obj上的属性parentObj.obj

相反,当您执行childObj.obj = ...时,您会在.obj上添加新属性childObj

childObj.obj = "child obj value"
console.log(Object.getOwnPropertyNames(childObj)) // ["obj"]

PS:如果您想了解有关hte主题的更多信息,我建议http://www.javascripttutorial.net/javascript-prototype/