为什么我们要用`Boy.prototype = new Human;`来模拟继承?
我不明白为什么每个人都使用 Boy.prototype = new Human; 来模拟继承。你看,我们想要的是A的函数吧?我们可以在不实例化一个新的 A 的情况下做到这一点(事实上,实例化一个新的 A 确实会给我们带来不想要的结果,因为我们实际上正在运行实例化函数,这不是我们想要的)
所以这不是一个更好的解决方案吗?
for (var prop_name in Human.prototype) {
Object.defineProperty(
Boy.prototype,
prop_name,
Object.getOwnPropertyDescriptor(Human.prototype,prop_name)
);
}
假设我们很特别,不仅想要 Human.prototype 中的可枚举属性,我们仍然可以通过使用 Object.getOwnPropertyNames
并在原型链上调用它来实现它,而原型链又可以通过 <代码>Object.getPrototypeOf。
那么,当我们有更好的选择时,使用 Boy.prototype = new Human; 来模拟继承到底有什么好处呢?
i don't get why everyone is using Boy.prototype = new Human;
to simulate inheritance. Look, what we want is the function's of A right? we can do that without instantiating a new A (in fact instantiating a new A does give us undesirable results, in the sense that we are actually running the instantiating function which isn't what we want)
So isn't this a better solution?
for (var prop_name in Human.prototype) {
Object.defineProperty(
Boy.prototype,
prop_name,
Object.getOwnPropertyDescriptor(Human.prototype,prop_name)
);
}
Say we are that particular and want not only the enumerable properties in Human.prototype we could still achieve it by using Object.getOwnPropertyNames
and calling it on the prototype chain, which in turn is available to us through Object.getPrototypeOf
.
So what exactly is the benefit of doing Boy.prototype = new Human;
to simulate inheritance when we have better options available to us?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
更好的选择是创建一个中间体来保存原型。
这避免了不必要的复制,但仍然意味着您不需要实例化将在其构造函数中工作的对象。它还设置了原型链,以便您可以使用instanceof。它也不会导致某些继承反模式可能造成的超类原型污染。
为了完整起见,您的子类应该在其构造函数中调用超类构造函数,您可以使用 Superclass.call(this); 来执行此操作。
编辑:从 ES5 开始,您可以替换对
extend
的调用,它可以执行相同的操作。
A better option is to create an intermediate to hold the prototype.
This avoids unnecessary copying, but still means that you don't need to instantiate an object that will do work in its constructor. It also sets up the prototype chain so that you can use instanceof. It also doesn't result in superclass prototype contamination which some inheritance antipatterns can.
For completeness, your subclass should call the superclass constructor in its constructor, which you can do with
Superclass.call(this);
.EDIT: Since ES5, you can replace calls to
extend
withwhich does the same thing.
instanceof
和isPrototypeOf()
会起作用有一些简单但丑陋的解决方法可以防止构造函数在您刚刚使用时执行其通常的初始化它创建一个原型对象。例如,您可以检查参数:
...或者将初始化移动到必须显式调用的单独方法中:
这有一个明显的缺点,即要求您记住调用
init()
每当你创建一个新的Boy
时。在 ECMAScript 5 环境中(例如,大多数浏览器的当前版本),更好的选择可能是 ECMAScript 5 的
Object.create()
,它允许您创建一个直接从另一个对象继承的对象,并为您设置原型链。这可以被模拟(但只是近似:参见ES5中的Object.defineProperty? ) 在非 ES5 环境中:instanceof
andisPrototypeOf()
will workThere are simple but ugly workarounds to prevent a constructor function from performing its usual initialization when you're just using it to create a prototype object. For example, you could either check the arguments:
... or move the initialization into a separate method that has to be called explicitly:
This has the obvious downside of requiring you to remember to call
init()
whenever you create a newBoy
.In ECMAScript 5 environments (current versions of most browsers, for example), a better option may be ECMAScript 5's
Object.create()
, which allows you to create an object which inherits directly from another object and sets up the prototype chain for you. This can be emulated (but only approximately: see Object.defineProperty in ES5?) in non-ES5 environments: