为什么我们构建原型继承链而不是使用对象组合。通过原型查看链中的每个步骤都很昂贵。
以下是一些虚拟示例代码:
var lower = {
"foo": "bar"
};
var upper = {
"bar": "foo"
};
var chained = Object.create(lower, pd(upper));
var chainedPrototype = Object.create(chained);
var combinedPrototype = Object.create(pd.merge(lower, upper));
var o1 = Object.create(chainedPrototypes);
var o2 = Object.create(combinedPrototypes);
使用pd
因为属性描述符很简陋。
o2.foo
比o1.foo
快,因为它只会上升两个原型链而不是三个。
由于在原型链上行进是昂贵的,为什么我们构造一个而不是使用对象组合?
另一个更好的例子是:
var Element = {
// Element methods
}
var Node = {
// Node methods
}
var setUpChain = Object.create(Element, pd(Node));
var chained = Object.create(setUpChain);
var combined = Object.create(pd.merge(Node, Element));
document.createChainedElement = function() {
return Object.create(chained);
}
document.createCombinedElement = function() {
return Object.create(combined);
}
我没有看到任何代码合并原型对象以提高效率。我看到很多代码构建了链式原型。为什么后者更受欢迎?
我能想到的唯一原因是使用Object.isPrototypeOf
来测试链中的各个原型。
除了isPrototypeOf
之外,使用继承而不是合成有明显的优势吗?
答案 0 :(得分:4)
主要原因必须是对原型对象的更改。对祖先对象的更改将反映在整个链中。可以想象,这可能是一种好处。虽然我不能立即想到任何真实世界的实例,但我认为拥抱这种动态性质可以提供动态,其他(阅读:基于类)语言根本无法提供。
原型链上的对象可以在应用程序的生命周期内根据需要发展,并且这些更改将反映在所有后代对象中。这可以很容易地与JavaScript的函数结合起来作为第一类对象,以根据需要动态修改功能。
也就是说,如果不需要此功能,则没有理由使用原型链而不是组合。
答案 1 :(得分:0)
好吧,考虑一下如果lower
或upper
发生变化会发生什么。由于您通过从中复制属性来创建新对象,因此组合原型不会反映出这种变化。
对于许多情况会很好的情况,但它肯定不像为对象实际构建正确的原型链那样动态。
答案 2 :(得分:0)
以下是我能按重要性考虑的一些好处
通过使用原型,您可以创建共享属性。您的方法将所有值复制到每个对象。
以为您稍后节省了一些时间,在设置对象时会产生复制属性的成本。在你的性能测试中考虑到这一点很好。如果您阅读的内容比设置对象的要多得多,则可能会超过这个好处。
好的代码不使用instanceOf,但有时候你不能完美地编写所有代码,为什么打破语言功能?
大多数人会声称他们从不需要这个(像我一样),但是我们中的许多人在实例化一些数组之后扩展了Array.prototype(不是你应该这样做)。使用复制属性方法,您将失去对原始对象的引用。
无耻插件:http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html
最后一点注意如果您实际上是应用程序的瓶颈,我不会不情愿将它用于有问题的对象