Javascript 对象定义技术,优点和缺点

标签 javascript object coding-style

在 Javascript 中定义可重用对象的基本方法有哪些?我说可重用是为了排除单例技术,比如直接用对象字面量表示法声明一个变量。我在某处看到 Crockford 在他的书中定义了四种这样的方法,但我宁愿不必为这一小段信息买一本书。

以下是我熟悉的方法:

  • this,用new构造(我觉得这叫经典?)

    function Foo() {
        var private = 3;
        this.add = function(bar) { return private + bar; }
    }
    
    var myFoo = new Foo();
    
  • 使用原型(prototype),类似

    function Foo() {
        var private = 3;
    }
    Foo.prototype.add = function(bar) { /* can't access private, correct? */ }
    
  • 返回文字,不使用 thisnew

    function Foo() {
        var private = 3;
        var add = function(bar) { return private + bar; }
        return {
            add: add
        };
    }
    
    var myFoo = Foo();
    

我可以想到这些可能无关紧要的相对较小的变化。我缺少什么样式?更重要的是,各自的优缺点是什么?有没有推荐的可以坚持,或者是偏好问题和圣战?

最佳答案

使用原型(prototype)。从构造函数返回特定对象会使它们成为非构造函数,而将方法分配给 this 会使继承变得不那么方便。

返回一个对象字面量

优点:

  • 如果一个人忘记了 new,他们仍然会得到对象。

  • 您可以创建真正私有(private)的变量,因为在构造函数中定义的对象的所有方法都共享其作用域。

缺点:

  • 它不是真正的构造函数。向其原型(prototype)添加内容不会更改返回的对象,无论是 new 还是没有 newnew Foo() instanceof Foo 也会导致 false

使用原型(prototype)

优点:

  • 让构造函数保持整洁。

  • 这是在 JavaScript 中做事的标准方式,所有内置构造函数都将它们的方法放在它们的原型(prototype)上。

  • 继承变得更容易、更正确;你可以(也应该)使用 Object.create(ParentConstructor.prototype) 而不是 new ParentConstructor(),然后从 中调用 ParentConstructor >构造函数。如果您想覆盖某个方法,可以在原型(prototype)上进行。

  • 您可以在创建对象后对其进行“修改”。

  • 您可以扩展您无权访问的构造函数的原型(prototype)。

缺点:

  • 它可能有点过于冗长,如果您想更改函数的名称,您还必须更改所有添加到原型(prototype)的函数。 (或者将原型(prototype)定义为一个大对象文字,并为 constructor 提供兼容的属性描述符。)

  • 它们不共享特定于实例的范围,因此您不能真正拥有私有(private)变量。

在构造函数中分配给this.*

优点:

  • 您可以使用闭包,因此可以使用私有(private)成员变量。

缺点:

  • 没有鸭子打字;您不能使用任何旧对象立即调用原型(prototype)的方法。例如,Array.prototype.slice.call(collectionLikeObject)

关于Javascript 对象定义技术,优点和缺点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6195898/

相关文章:

javascript - CryptoJS DES (ECB) 加密 - Base64 编码 - 未产生正确的结果

javascript - chart.js 图表以固定宽度扭曲

php - javascript打印所有表和单个表

javascript - js中内置对象类型在控制台中的不同类型名称

c++ - 如何在没有 'new' 的情况下将新对象实例添加到 std::list

c# - .NET 中的编码风格 : whether to refactor into new method or not?

javascript - Reactjs使用状态: select onChange triggers setState but component doesn't re-render

c# - 将大括号用于可变范围目的是错误的吗?

android - 我应该扩充布局还是以编程方式创建它?

安卓初始化动画