在Derived.prototype = new Base中使用'new'关键字的原因是什么 [英] What is the reason to use the 'new' keyword at Derived.prototype = new Base
问题描述
以下代码执行的操作:
WeatherWidget.prototype = new Widget;
其中 Widget
是一个构造函数,想要使用新的函数 WeatherWidget
扩展Widget的类。
<$> c $ c> new 关键字在那里,如果它被遗漏会发生什么?
WeatherWidget.prototype = new Widget;
新
c> Widget 作为构造函数,并将返回值分配给原型
属性。 (如果您省略 new
,除非您添加了参数列表,否则不会调用 Widget
, Widget
的方式可能是不可能的,它肯定有潜力破坏全局命名空间如果它不是严格模式代码,并且实现符合ECMAScript Ed。5.x,那么因为构造函数中的这个
将引用ECMAScript的全局对象。 )
但这种方法实际上来自真正病毒
在Netscape JavaScript 1.3指南中, =nofollow noreferrer> p>这样,您的 WeatherWidget
实例将全部继承自相同的 Widget
实例。原型链将是:
[new WeatherWidget()]→[new Widget()]→[Widget.prototype]→ ...
这可能很有用,但大多数时候你不会希望它发生。除非您希望所有 WeatherWidget
实例在 之间共享属性值这个 Widget
实例,并且只有通过它,从 Widget.prototype
。另一个问题是你需要以这种方式调用父构造函数,这可能不允许在没有参数的情况下调用,或者不能正确初始化。它当然与基于类的继承的仿真无关,例如从Java。
在这些基于原型的实现中实现基于类的继承的正确方法语言(最初是由 Lasse Reichstein Nielsen在 comp.lang.javascript
在2003年,用于克隆对象):
function Dummy (){}
Dummy.prototype = Widget.prototype;
WeatherWidget.prototype = new Dummy();
WeatherWidget.prototype.constructor = WeatherWidget;
(构造函数
以及, WeatherWidget
实例 w
会有 w.constructor === WeatherWidget
,而不是 w.constructor === Widget
。但是,请注意它之后是可枚举的。)
这样, WeatherWidget
实例将通过原型链继承属性,但不会在它们之间共享属性值,因为它们继承自 Widget.prototype
通过 Dummy
没有自己的属性:
[new WeatherWidget()]→[new Dummy()]→[Widget.prototype]→...
父构造函数只有在您从 WeatherWidget
中明确调用时才会被调用,例如使用
function WeatherWidget(...)
{
Widget.apply(this,arguments);
}
(如果你处在一个非常受限制的环境中,需要符合ECMAScript Ed。 5和更高版本,所以不是在网上 - 或ECMAScript版本5.1的实施已经变得无处不在 - 从现在开始10年左右,考虑到第3版是长期,你可以并应该使用 WeatherWidget.prototype =
Object.create
(Widget.prototype,{constructor:{value:WeatherWidget}});
还有一个额外的优点,即所产生的构造函数
属性是 not writable,enumerable,or configurable 。)
另请参阅 Function.prototype.extend()
在我的 JSX:object.js 中了解如何推广。使用该代码,它将成为
WeatherWidget.extend(Widget);
My Function.prototype.extend()
采用可选的第二个参数,您可以轻松地扩充 WeatherWidget
实例的原型:
WeatherWidget.extend(Widget,{
foo:42,
bar:baz
});
将等同于
WeatherWidget.extend(Widget);
WeatherWidget.prototype.foo = 42;
WeatherWidget.prototype.bar =baz;
你仍然需要在子构造函数中显式调用父构造函数;该部分不能合理地自动化。但是我的 Function.prototype.extend()
向 Function >添加了
_super
code> instance更容易:
function WeatherWidget(...)
{
WeatherWidget ._super.apply(this,arguments);
}
其他人已实施类似的扩展。
What does the following code do:
WeatherWidget.prototype = new Widget;
where Widget
is a constructor, and I want to extend the Widget 'class' with a new function WeatherWidget
.
What is the new
keyword doing there and what would happen if it is left out?
WeatherWidget.prototype = new Widget;
The new
keyword calls Widget
as a constructor and the return value is assigned to the prototype
property. (If you would omit new
, you would not call Widget
unless you added an argument list, ()
. However, calling Widget
that way might not be possible. It would certainly have the potential to spoil the global namespace if it is not strict mode code and the implementation is conforming to ECMAScript Ed. 5.x there, because then this
in the constructor would refer to ECMAScript’s global object.)
But this approach actually comes from a really viral bad example in the old Netscape JavaScript 1.3 Guide (mirrored at Oracle, formerly Sun).
This way, your WeatherWidget
instances will all inherit from the same Widget
instance. The prototype chain will be:
[new WeatherWidget()] → [new Widget()] → [Widget.prototype] → …
This can be useful, but most of the time you would not want it to happen. You should not do that here unless you want all your WeatherWidget
instances to share among them the property values they inherit from this Widget
instance, and only through it, from Widget.prototype
. Another problem is that you need to call the parent constructor this way, which may not allow to be called without arguments as you do, or would not initialize properly. It certainly has nothing to do with emulation of class-based inheritance as known, e.g., from Java.
The proper way to implement class-based inheritance in these prototype-based languages is (originally devised by Lasse Reichstein Nielsen in comp.lang.javascript
in 2003, for cloning objects):
function Dummy () {}
Dummy.prototype = Widget.prototype;
WeatherWidget.prototype = new Dummy();
WeatherWidget.prototype.constructor = WeatherWidget;
(The constructor
prototype property should be fixed as well, so that your WeatherWidget
instances w
would have w.constructor === WeatherWidget
as expected, and not w.constructor === Widget
. However, be aware that it is enumerable afterwards.)
This way, WeatherWidget
instances will inherit properties through the prototype chain, but will not share property values among them, because they inherit from Widget.prototype
through Dummy
which has no own properties:
[new WeatherWidget()] → [new Dummy()] → [Widget.prototype] → …
The parent constructor will only be called if you call it explicitly, from WeatherWidget
, for example with
function WeatherWidget (…)
{
Widget.apply(this, arguments);
}
(If you are in a very restricted environment that requires compliance with ECMAScript Ed. 5 and later – so not on the Web – or when implementations of ECMAScript Edition 5.1 have become ubiquitous – in 10 years or so from now, given that it took Edition 3 that long –, you can and should use WeatherWidget.prototype =
Object.create
(Widget.prototype, {constructor: {value: WeatherWidget}});
instead. This has the additional advantage that the resulting constructor
property is not writable, enumerable, or configurable.)
See also Function.prototype.extend()
in my JSX:object.js for how to generalize this. Using that code, it would become
WeatherWidget.extend(Widget);
My Function.prototype.extend()
takes an optional second argument with which you can easily augment the prototype of WeatherWidget
instances:
WeatherWidget.extend(Widget, {
foo: 42,
bar: "baz"
});
would be equivalent to
WeatherWidget.extend(Widget);
WeatherWidget.prototype.foo = 42;
WeatherWidget.prototype.bar = "baz";
You will still need to call the parent constructor explicitly in the child constructor, though; that part cannot reasonably be automated. But my Function.prototype.extend()
adds a _super
property to the Function
instance which makes it easier:
function WeatherWidget (…)
{
WeatherWidget._super.apply(this, arguments);
}
Other people have implemented similar extensions.
这篇关于在Derived.prototype = new Base中使用'new'关键字的原因是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!