Javascript 使用';新';关键字at Derived.prototype=新基
以下代码的作用是什么:Javascript 使用';新';关键字at Derived.prototype=新基,javascript,constructor,prototype,Javascript,Constructor,Prototype,以下代码的作用是什么: WeatherWidget.prototype = new Widget; 其中Widget是一个构造函数,我想用一个新函数WeatherWidget扩展Widget'class' 新的关键字在那里做什么?如果忽略它会发生什么 根据一些奇怪的Javascript规则,newwidget实际上调用构造函数,而不是返回对构造函数的引用。这个问题实际上回答了var a=newwidget()和var a=Widget()之间的区别 简单地说,new关键字告诉Javascrip
WeatherWidget.prototype = new Widget;
其中Widget
是一个构造函数,我想用一个新函数WeatherWidget
扩展Widget'class'
新的
关键字在那里做什么?如果忽略它会发生什么 根据一些奇怪的Javascript规则,newwidget
实际上调用构造函数,而不是返回对构造函数的引用。这个问题实际上回答了var a=newwidget()
和var a=Widget()之间的区别
简单地说,new
关键字告诉Javascript在与常规函数调用不同的规则集下调用函数Widget
。在我脑海中,我记得的是:
创建了一个全新的对象
Widget
可以使用this
关键字来引用该对象
如果Widget
未返回任何内容,则将创建此新对象
此对象将继承一些附加属性,这些属性将指示它是由用于跟踪属性链的小部件创建的
如果没有new
关键字,调用widget将
如果处于严格模式,此
将设置为未定义。
否则,此
将引用全局对象。(通过浏览器调用窗口
)
如果函数不返回任何内容,则将返回undefined
参考:
对于原型继承很重要;i、 e.
使用方法创建构造函数
var Obj = function(){};
Obj.prototype = {};
Obj.prototype.foo = function(){console.log('foo');};
创建第二个构造函数来扩展第一个构造函数
var ExObj = function(){};
现在,如果我们在原型中没有新的
ExObj.prototype = Obj;
(new ExObj).foo(); // TypeError: Object #<Object> has no method 'foo'
此外,向ExObj
原型添加新内容不会对其基础Obj
进行任何更改
WeatherWidget.prototype = new Widget;
创建小部件
构造函数的新实例,并将其用作WeatherWidget
的原型对象。使用创建新对象,将其继承链设置为小部件.prototype
,并在其上应用构造函数(您可以在其中设置单个属性'n'方法,或创建私有范围的变量)
如果没有new
关键字,则将小部件
功能分配给原型
属性,这没有任何意义。如果您添加可选括号(即Widget()
),它将正常调用函数,但不是作为新实例上的构造函数,而是以全局对象作为上下文。另见
请注意,您不应该真正使用此代码。如上所述,它通过调用构造函数创建一个新实例。但其目的只是创建一个从小部件
的原型对象继承的空对象,而不是实例化某些东西(这可能会造成一些伤害,具体取决于代码)。相反,您应该使用(或其):
另请参见用通俗易懂的英语,您正在用一个类扩展另一个类。原型只能是一个对象,因此您可以将WeatherWidget
的原型设置为Widget
的新实例。如果删除了new
关键字,则将原型设置为literal构造函数,而该构造函数什么也不做
var Appendages = function(){
this.legs = 2
};
var Features = function() {
this.ears = 4;
this.eyes = 1;
}
// Extend Features class with Appendages class.
Features.prototype = new Appendages;
var sara = new Features();
sara.legs;
// Returns 2.
理解原型可以是任何对象,类似这样的东西也会起作用:
var appendages = {
legs : 2
};
var Features = function() {
this.ears = 4;
this.eyes = 1;
}
// Extend Features class with Appendages class.
Features.prototype = appendages;
var sara = new Features();
sara.legs;
// Returns 2.
在JavaScript中,如果在对象上找不到键,它会检查扩展它的父对象。因此,您可以动态更改父对象上的项目,如下所示:
var appendages = {
legs : 2
};
var Features = function() {
this.ears = 4;
this.eyes = 1;
}
// Extend Features class with Appendages class.
Features.prototype = appendages;
var sara = new Features();
sara.legs;
// Returns 2.
appendages.hair = true;
sara.hair;
// Returns true.
请注意,所有这些都发生在实例化过程中,这意味着您不能在创建对象后仅切换原型:
var foo = {name : 'bob'};
var bar = {nachos : 'cheese'};
foo.prototype = bar;
foo.nachos;
// undefined
但是,所有现代浏览器都提供了这种较新的\uuuuuuuuuuuuuuuuuuuuuu
方法,允许您执行以下操作:
var foo = {name : 'bob'};
var bar = {nachos : 'cheese'};
foo.__proto__ = bar;
foo.nachos
// "cheese"
阅读更多关于理解JavaScript原型的内容。
来自Pivotal实验室的这也非常好
WeatherWidget.prototype = new Widget;
new
关键字作为构造函数调用Widget
,返回值分配给prototype
属性。(如果省略new
,除非添加参数列表,()
。但是,以这种方式调用小部件
可能是不可能的。如果它不是严格的模式代码,并且实现符合ECMAScript Ed.5.x,则肯定有可能破坏全局命名空间,因为构造函数中的此
将引用ECMAScript的全局对象。)
但这一方法实际上来自于一个公司(Oracle,前身为Sun)
这样,您的WeatherWidget
实例将全部继承自同一Widget
实例。原型链将是:
[new WeatherWidget()] → [new Widget()] → [Widget.prototype] → …
这可能是有用的,但大多数情况下,你不希望它发生。除非您希望所有WeatherWidget
实例在它们之间共享从Widget
实例继承的属性值,并且仅通过它从Widget.prototype
继承的属性值,否则不应在此处执行此操作。另一个问题是,您需要以这种方式调用父构造函数,这可能不允许像您这样在没有参数的情况下调用,或者无法正确初始化。它当然与基于类的继承的模拟无关,例如来自Java的继承
在这些基于原型的语言中实现基于类的继承的正确方法是(最初由以下人员设计):
constructor
prototype属性也应该是固定的,这样您的WeatherWidget
实例w
将具有预期的w.constructor===WeatherWidget
,而不是w.constructor==Widget
。但是,请注意,它是可枚举的
这样,,
WeatherWidget.prototype = new Widget;
[new WeatherWidget()] → [new Widget()] → [Widget.prototype] → …
function Dummy () {}
Dummy.prototype = Widget.prototype;
WeatherWidget.prototype = new Dummy();
WeatherWidget.prototype.constructor = WeatherWidget;
[new WeatherWidget()] → [new Dummy()] → [Widget.prototype] → …
WeatherWidget.prototype = Object.create(Widget.prototype, {
constructor: {value: WeatherWidget}
});
function WeatherWidget (…)
{
Widget.apply(this, arguments);
}
WeatherWidget.extend(Widget);
WeatherWidget.extend(Widget, {
foo: 42,
bar: "baz"
});
WeatherWidget.extend(Widget);
WeatherWidget.prototype.foo = 42;
WeatherWidget.prototype.bar = "baz";
function WeatherWidget (…)
{
WeatherWidget._super.apply(this, arguments);
}