Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用';新';关键字at Derived.prototype=新基_Javascript_Constructor_Prototype - Fatal编程技术网

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);
    }