【问题标题】:Is it ok to assign the JavaScript prototype object instead of just its properties?可以分配 JavaScript 原型对象而不仅仅是其属性吗?
【发布时间】:2011-09-09 12:52:16
【问题描述】:

在 JavaScript 中,我们可以为函数的原型分配属性或直接设置其原型对象:

var MyClass = function() { };

// The "property" form...
MyClass.prototype.foo = function() { ... };
MyClass.prototype.bar = function() { ... };
MyClass.prototype.gah = function() { ... };

// OR the "assignment" form...
MyClass.prototype = {
  foo:function() { ... },
  bar:function() { ... },
  gah:function() { ... }
};

我个人更喜欢赋值形式,因为您可以轻松地将对象包装在闭包中(例如隐藏“私有”对象),如果您以后决定更改“MyClass”的名称,您只需找到两个位置而不是可能的几十个。 (当然,“属性”形式也可以这样说,通过使用和调用以现有原型作为参数的函数,但在我看来“赋值”形式似乎更直接。)

是否有充分的理由使用一种形式而不是另一种形式?

[编辑]

正如评论者@Raynos 所提到的,第二种形式(赋值)破坏了prototype.constructor 属性,该属性应设置为 MyClass 函数(默认情况下为第一种形式 [property])。这有什么真正的缺点吗(除了属性没有设置的事实)?

【问题讨论】:

    标签: javascript prototype-programming


    【解决方案1】:

    我认为使用 Object.assign 在不破坏当前原型的情况下分配函数原型的最佳方法。

    function myFunction() {
    
    }
    
    Object.assign(myFunction.prototype, {
        say(str) { return str },
        greet(name) { return "Hello " + name}
    })
    

    【讨论】:

      【解决方案2】:

      自 EcmaScript2015 以来,几乎没有理由再摆弄prototype 属性了。

      class 语法以更直观的语法提供所需内容:

      class MyClass {
          constructor() { }
          foo() { ... }
          bar() { ... }
      }
      

      ...当需要更长的原型链时:

      class MySuperClass {
          constructor() { }
          foo() { ... }
          bar() { ... }
      }
      
      class MyClass extends MySuperClass{
          constructor() { }
          gah() { ... }
      }
      

      【讨论】:

        【解决方案3】:

        我认为对prototype 属性使用“赋值”形式还有另一个缺点:当您处理“伪经典”继承时,您可能会清除prototype.__proto__ 属性(原型链) .

        当然,有人可能会争辩说有一种可疑的方法来解决这个问题,那就是自己附加__proto__ 属性以再次连接链。但是如果你调用父方法,忘记这样做会破坏代码。在这里查看我的小提琴:http://jsfiddle.net/glenn/v5Yub/

        结论:“assignment”表单可能看起来更简单/干净,但“property”表单更安全。

        【讨论】:

        【解决方案4】:

        不使用第二种形式的最大原因是您最终会在分配原型之前消除原型中存在的任何其他内容。如果这不是您关心的事情,那么没有理由不按照您演示的方式声明它。

        【讨论】:

        • 特别是.prototype.constructor 属性应该是MyClass
        • @Raynos:感谢您的意见 - 忘记将 prototype.constructor 分配给 MyClass 函数有什么缺点?
        • 您可以通过在新属性对象中添加constructor: MyClass 或更一般的constructor: Myclass.prototype.constructor 来保留构造函数。
        猜你喜欢
        • 2019-01-09
        • 2016-03-26
        • 2019-09-03
        • 2020-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多