【问题标题】:Understanding prototype Property of function了解原型函数的属性
【发布时间】:2015-07-07 19:05:23
【问题描述】:

举个例子

var Func = function(){}

这里 Func 有一个名为原型的属性,我可以添加我的自定义方法,如下所示。

Func.prototype.move = function(){ //do something }

根据我的理解,原型只是 Func 的另一个属性,默认情况下由解释器提供,不用于委托任何功能,即。没有什么像

Func.move()

应用相同的逻辑,我正在创建相同函数的另一个属性,如下所示

Func.method = function(){ //do something }

现在如果创建一个新对象

var obj = new Func();

这里有obj.move(),但obj.method() 不会在那里。如果原型只是另一个没有神奇优势的属性,那么为什么会有这种行为呢?提前致谢!

【问题讨论】:

  • 你错了。函数的prototype 属性神奇的。
  • prototype 属性用于在prototype chain 中查找属性/函数。因此,当您询问任何object 中的property 时,首先它会查找object 本身,如果未找到,则通过objectprototypical chain 搜索到Object。对您的示例非常特别,您将method 属性直接添加到Func 对象上,因此在这种情况下,它仅在Func 上的该实例上可用,并且您将move 属性添加到@ 的原型987654341@,因此将通过prototypical chain lookup 提供。

标签: javascript prototype


【解决方案1】:

当您使用new 时,函数的prototype 属性将用作实例对象的内部[[Prototype]] 属性的模板。这在某些浏览器中以__proto__ 公开,不要与prototype 混淆,prototype 只是一个常规属性。

当您直接将属性附加到函数时,与prototype 不同,您基本上将函数用作命名空间。由于函数是对象,因此它们可以具有任意属性,并且其他属性是内置的,例如 prototypename。实际上,您正在创建类似于静态方法的东西,它不依赖于实例,不使用this

【讨论】:

    【解决方案2】:

    函数的prototype属性确实有一个特殊的用途:它将被设置为使用这个函数作为构造函数创建的对象的内部原型(即当你使用new时)。

    所以当你写var obj = new Func();时,obj没有自己的属性move,但是当查找失败时,它被向上委托原型链:到obj的原型,也就是你之前设置的 Func.prototype,它确实有一个 move 方法。

    另一方面,向 Func 添加 move 只是创建函数本身的属性(函数也是对象,因此您可以向它们添加属性) - 您可以使用 @987654326 调用它@,但它与obj基本无关。

    如果你想详细了解函数原型属性的工作原理,我推荐 Eloquent Javascript 的章节The Secret Life of Objects

    【讨论】:

      【解决方案3】:

      使用 move,您将函数添加到对象的原型中,因此它可用于新创建的对象。 使用方法,您将函数添加到 已经创建的 对象 Func。

      【讨论】:

        【解决方案4】:

        prototype 属性用于在prototype chain 中查找属性/函数。因此,当您询问任何object 中的property 时,首先它会查找object 本身,如果未找到,则通过objectprototypical chain 搜索到Object。对您的示例非常特别,您正在将 method 属性直接添加到 Func 对象上,因此在这种情况下,它仅在 Func 上的该实例上可用,并且您正在将 move 属性添加到 @ 的原型987654333@,因此将通过prototypical chain lookup 提供。

        【讨论】:

          【解决方案5】:

          下面的代码应该解释了区别:

          Func = function(){};
          
          Func.prototype.move = function(){ 
              alert('move');
          }
          
          Func.method = function(){ 
              alert('method');
          };
          
          var obj = new Func();
          //valid since move is defined using prototype and hence available on all instances of Func
          obj.move(); 
          //valid since you just added a method to Func and invoking it directly using Func
          Func.method();
          
          //invalid since method was not defined using prototype
          obj.method();
          //invalid since move was not defined using prototype and hence available only on instances of Func and not as a property of Func
          Func.move();

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-01-07
            • 1970-01-01
            相关资源
            最近更新 更多