假设我有类似的对象关系;
{{1}}
在上面的代码中,当我创建了第三个对象时,它还将继承预期的firstObject属性。我想知道的是,有没有优雅(我的意思是没有 使用hasOwnProperty属性迭代secondObject属性的方法 在创建thirdObject时只继承secondObject属性?
答案 0 :(得分:3)
有没有优雅(我的意思是没有使用hasOwnProperty属性迭代secondObject属性)在创建thirdObject时只继承secondObject属性的方法?
不,事实上,也没有(合理的)不优雅的方式去做;从thirdObject
生成secondObject
继承意味着它将继承所有secondObject
的属性以及其原型中的属性。
如果您希望thirdObject
不拥有firstObject
的属性,则thirdObject
不应该(间接)从firstObject
继承。
你有三个选择("不合理"第四个以后):
您可以使用Object.assign
将 secondObject
自己的属性复制到thirdObject
:
var thirdObject = Object.assign({}, secondObject);
...但它不会是继承,只是一个快照。但这可能是最好的。 (Object.assign
已添加到ES2015 [aka" ES6"]中,但可以为旧的JavaScript引擎进行填充。)
或者,这确实需要迭代secondObject
自己的属性,您可以为getter和setter提供thirdObject
匹配属性:
var firstObject = { prop1:"prop1", prop2:"prop2" };
var secondObject = Object.create(firstObject);
secondObject.prop3 = "prop3";
secondObject.prop4 = "prop4";
var thirdObject = {};
Object.keys(secondObject).forEach(function(key) {
Object.defineProperty(thirdObject, key, {
get: function() {
return secondObject[key];
},
set: function(value) {
delete this[key]; // Release the getter/setter for this
this[key] = value; // ...and make it an own property
},
configurable: true,
enumerable: true
});
});
console.log("prop1" in firstObject); // true
console.log("prop1" in secondObject); // true
console.log("prop1" in thirdObject); // false
console.log("--");
console.log("prop3" in firstObject); // false
console.log("prop3" in secondObject); // true
console.log("prop3" in thirdObject); // true
console.log("--");
console.log(firstObject.prop1); // prop1
console.log(secondObject.prop1); // prop1
console.log(thirdObject.prop1); // undefined
console.log("--");
console.log(firstObject.prop3); // undefined
console.log(secondObject.prop3); // prop3
console.log(thirdObject.prop3); // prop3

.as-console-wrapper {
max-height: 100% !important;
}

在那里,我们模仿继承,让thirdObject
从secondObject
获取值,直到/除非有东西给它赋值,在这种情况下我们将它作为标准数据属性。
或者你可以让thirdObject
继承一个忠实于secondObject
自己的属性的中间人(更简单一点,然后"拥有"标志是右):
var firstObject = { prop1:"prop1", prop2:"prop2" };
var secondObject = Object.create(firstObject);
secondObject.prop3 = "prop3";
secondObject.prop4 = "prop4";
var thirdProto = {};
Object.keys(secondObject).forEach(function(key) {
Object.defineProperty(thirdProto, key, {
get: function() {
return secondObject[key];
},
configurable: true,
enumerable: true
});
});
var thirdObject = Object.create(thirdProto);
console.log("prop1" in firstObject); // true
console.log("prop1" in secondObject); // true
console.log("prop1" in thirdObject); // false
console.log("--");
console.log("prop3" in firstObject); // false
console.log("prop3" in secondObject); // true
console.log("prop3" in thirdObject); // true
console.log("--");
console.log(firstObject.prop1); // prop1
console.log(secondObject.prop1); // prop1
console.log(thirdObject.prop1); // undefined
console.log("--");
console.log(firstObject.prop3); // undefined
console.log(secondObject.prop3); // prop3
console.log(thirdObject.prop3); // prop3

.as-console-wrapper {
max-height: 100% !important;
}

* 不合理的方式是使用Proxy
(ES2015 +,而非polyfillable):
var firstObject = { prop1:"prop1", prop2:"prop2" };
var secondObject = Object.create(firstObject);
secondObject.prop3 = "prop3";
secondObject.prop4 = "prop4";
var thirdObject = Object.create(new Proxy(secondObject, {
has: function(target, prop) {
return target.hasOwnProperty(prop) || secondObject.hasOwnProperty(prop);
},
get: function(target, prop) {
return target.hasOwnProperty(prop) || secondObject.hasOwnProperty(prop) ? target[prop] : undefined;
},
set: function(target, prop, value) {
target[prop] = value;
return true;
}
}));
console.log("prop1" in firstObject); // true
console.log("prop1" in secondObject); // true
console.log("prop1" in thirdObject); // false
console.log("--");
console.log("prop3" in firstObject); // false
console.log("prop3" in secondObject); // true
console.log("prop3" in thirdObject); // true
console.log("--");
console.log(firstObject.prop1); // prop1
console.log(secondObject.prop1); // prop1
console.log(thirdObject.prop1); // undefined
console.log("--");
console.log(firstObject.prop3); // undefined
console.log(secondObject.prop3); // prop3
console.log(thirdObject.prop3); // prop3

.as-console-wrapper {
max-height: 100% !important;
}

Note: Requires a browser with <code>Proxy</code> support.
&#13;
... 但是我无法想象您在继承链中想要一个代理对象,尤其是因为它会对性能产生影响。 :-)所以我不会这样做。 (而且我确定上面的例子不完整。)