这些不同的对象创建方法在JavaScript中的适当应用是什么

Ben*_*old 5 javascript oop

我不仅仅是一个后端人而不是前端人,但JavaScript让我很感兴趣.我试图围绕我看来是多种不同的对象建模方法.

在过去的几年里,我一直主要编写与此类似的代码(假设加载了jQuery):

var TicketForm = {

    elements: ['input', 'textarea', 'select', 'checkbox'],

    enable: function(form) {
        this.elements.forEach( function(el) {
            form.find(el).prop('disabled', false);
        });
    },

    disable: function(form) {
        this.element.forEach( function(el) {
            form.find(el).prop('disabled', true);
        });
    }
};
Run Code Online (Sandbox Code Playgroud)

这样我就可以简单地调用TicketForm.enable($('#whatever'));启用一个特定的表单,非常类似于PHP中的静态方法调用.

我最近一直在使用PHP中的闭包,我知道它们在JavaScript中也存在(我正在使用它们).我正在努力更彻底地掌握这个概念.在遇到这个令人惊讶的剧本之后:http://codepen.io/stuffit/pen/KrAwx,我决定尝试模仿该作者的编码风格.只是试图复制他的风格,我重写了我的代码:

var TicketForm = function() {
    this.elements = ['input', 'textarea', 'select', 'checkbox'];
};

TicketForm.prototype.enable = function(form) {
    this.elements.forEach( function(el) {
        form.find(el).prop('disabled', false);
    });
};

TicketForm.prototype.disable = function(form) {
    this.elements.forEach( function(el) {
        form.find(el).prop('disabled', true);
    });
};
Run Code Online (Sandbox Code Playgroud)

但是,当我TicketForm.enable($('#whatever'));在这种情况下打电话时,我收到错误

Uncaught TypeError: Object function () {
    this.elements = ['input', 'textarea', 'select', 'checkbox'];
} has no method 'enable'
Run Code Online (Sandbox Code Playgroud)

所以我对SO进行了一些挖掘,发现JavaScript .prototype是如何工作的?.第二个答案尤其具有启发性,因为我来自阶级概念背景而非原型概念背景.我还翻阅了一些幻灯片:http://ejohn.org/apps/learn/#65,这也很有帮助.事实证明,我所要做的就是创建一个TicketForm实例,这时我的方法就可以了:

var myForm = new TicketForm();
myForm.enable(form); // works as expected
Run Code Online (Sandbox Code Playgroud)

我有三个问题:

  1. 除了个人编码风格之外,为什么选择上述任何一种方法而不是另一种?
  2. 为什么我必须使用第二种方法声明对象的实例,而我不使用第一种方法?
  3. 这些编码风格中是否有正确的名称?

jua*_*azo 2

在 JavaScript 中,对象默认是可变的。这意味着,除非您使用现代 JavaScript 引擎并且有人故意阻止对象被修改,否则您始终可以添加、删除和修改对象中的属性。

在第一种情况下,您使用特殊语法来简化对象创建。该{}语法创建一个简单的对象,它只不过是 的一个实例Object。这与 JS 中对象的可变性相结合,意味着以下代码片段都是等效的:

var TicketForm = {
  elements: ['input', 'textarea', 'select', 'checkbox']
};

var TicketForm = {};
TicketForm.elements = ['input', 'textarea', 'select', 'checkbox'];

var TicketForm = new Object();
TicketForm.elements = ['input', 'textarea', 'select', 'checkbox'];
Run Code Online (Sandbox Code Playgroud)

本质上,使用{}类似于在经典 OOP 语言中创建对象的实例,而创建构造函数类似于使用类。在构造函数及其原型中,您定义一个蓝图,该构造函数的所有实例(共享该原型的所有对象)都将采用该蓝图。

所以这不是风格的问题,而是你需要创造什么的问题。如果您需要同一事物的多个副本,则可以使用构造函数。如果您只需要一个,只需创建一个普通对象,无需遵循礼仪,创建一个单例并一式三份地签署所有内容;)