【问题标题】:Using "this.prototype" vs outer "Constructor.prototype" in OOP在 OOP 中使用“this.prototype”与外部“Constructor.prototype”
【发布时间】:2014-02-16 16:06:40
【问题描述】:

在 JavaScript 中,定义类(构造函数)函数方法通常是这样完成的:

function Class1() {
   // ... code ...
}
Class1.prototype.method1 = function(args) {
   // ... code ...
};

按照 ECMAScript 的一般语法/语义规则,我没有理由不能覆盖/更改/扩展原始 Object.prototype

function Class1() {
   // ... code ...
   this.prototype.method1 = function(args) {
      // ... code ...
   };
}

那为什么不这样做呢?代码看起来有点混乱,但写和读起来更快更干净(将所有与 Class1 相关的方法放在 Class1 本身的下面)。这不是更好的用途吗?

【问题讨论】:

  • 您的第二个示例代码将不起作用。构造函数内部this的值不是构造函数;它是新创建的对象的值。
  • 那我可以通过this.constructor访问它吗?我不妨编辑我的问题。
  • 构造函数为实例化的每个对象运行。每次构建新对象时,您都会向原型添加一组新的相同函数,这对性能有相当大的影响。
  • 我强烈建议您查看augment 项目。即使您不使用该库,代码也是了解这些东西如何工作的好方法。
  • 关于原型和构造函数的解释我已经创建了这个答案,希望对您有所帮助。stackoverflow.com/a/16063711/1641941

标签: javascript oop syntax prototype


【解决方案1】:

这两段代码绝对相同;第二个不行。

构造函数中发生的事情(通常)与原型对象无关。它是每个实例的初始化代码。感兴趣的“原型”属性是构造函数的“原型”属性,而不是实例的。

在构造函数中创建原型函数没有意义,因为这意味着你要为你创建的每个实例重新做这项工作。

【讨论】:

  • 好吧,我想我现在明白了。谢谢!
【解决方案2】:

问题是这两个代码示例不等效。在第一个示例中,“this”指的是 Class1,但在第二个示例中,“this”指的是新创建的对象。例如,

var myObj = new Class1()

在上面的例子中,'this' 是 myObj - 这打破了你的第二个例子。

此外,即使这确实有效,您也会为您创建的每个实例重新创建该方法。不这样做会更有效率。

【讨论】:

    【解决方案3】:

    正如其他答案所指出的,原型的第二次使用不是有效的 javascript 代码,但您似乎希望在构造函数实际运行时访问它,这可以通过以下两个选项实现:

    1-如果你不使用严格模式,你可以这样:

      var MyClass = function ClassConstructor(){
             arguments.callee.prototype. ...
      }
    

    2- 在严格模式下,例如,如果您有类似类的函数,例如:

    var MyClass = function ClassConstructor(){
            ClassConstructor.prototype. ...
     }
    

    这样你只能在构造函数中使用 ClassConstructor,它是私有的。

    【讨论】:

      【解决方案4】:

      即使您修复了代码,以指向正确的 this,原型属性也会在创建时添加到每个实例。

      但它们是通过共享方法/属性的相同副本添加的。

      如果不叫原型:如果叫“Bob”,用手抄,就更有意义了:

      var Bob = {
          name : "Bob",
          sayName: function ( ) {
               var person = this;
               console.log( "My name is " + person.name );
          }
      };
      
      
      
       var Person = function (name) {
          var person = this;
          person.name = name || Bob.name;
          person.sayName = Bob.sayName;
       };
      
      
      var doug = new Person("Doug"),
          jim  = new Person("Jim");
      

      在幕后经常发生一些事情,但在 Bob 和通常的 Person.prototype 之间并没有太大区别。

      但你可以清楚地看到为什么你不想在每次创建一个新人时重置 Bob.name。

      【讨论】:

        猜你喜欢
        • 2010-10-13
        • 1970-01-01
        • 2023-03-22
        • 1970-01-01
        • 2012-01-13
        • 1970-01-01
        • 2017-01-31
        • 1970-01-01
        相关资源
        最近更新 更多