在JavaScript中,这些不同的对象创建方法的正确应用是什么?
What are the proper applications of these different methods of object creation in JavaScript
我更喜欢后端而不是前端,但是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);
});
}
};
这样,我可以简单地调用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);
});
};
然而,当我在这种情况下调用TicketForm.enable($('#whatever'));
时,我得到错误
Uncaught TypeError: Object function () {
this.elements = ['input', 'textarea', 'select', 'checkbox'];
} has no method 'enable'
所以我对So做了一点挖掘,发现JavaScript .prototype是如何工作的?第二个答案尤其具有启发性,因为我来自类概念背景,而不是原型概念背景。我还浏览了一些幻灯片:http://ejohn.org/apps/learn/#65,这也很有帮助。事实证明,我所要做的就是创建TicketForm的实例,此时它的方法对我可用:
var myForm = new TicketForm();
myForm.enable(form); // works as expected
我有三个问题:
- 为什么,除了个人的编码风格,一个人会选择上面的方法之一,而不是另一个?
- 为什么我必须用第二个方法声明对象的实例,而我不用第一个方法?
- 这些编码风格都有合适的名称吗?
你的第一个方法定义了一个对象字面量,基本上创建了一个"单例"。如果你需要同一个"类"的多个实例,你需要一个构造函数(或Object.create
)。
在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'];
本质上,使用{}
类似于在经典OOP语言中创建对象的实例,而创建构造函数类似于使用类。在构造函数及其原型中,你定义了一个蓝图,该构造函数的所有实例(共享该原型的所有对象)都将采用该蓝图。
所以这不是关于风格,而是关于你需要创造什么。如果需要同一事物的多个副本,可以使用构造函数。如果你只需要一个,就创建一个普通对象,不需要遵循礼仪,创建一个单例,并以三份的形式签署所有内容;)
第一个方法是一个"字面对象",很像一个静态类,"this"指的是父对象"TicketForm",你可以把它理解为一个"self"。在第二个方法中"this"指的是窗口,它不是oo,除非你做:
var myForm = new TicketForm();
这里的"this"指的是myForm实例。这个方法是"构造函数"方法(TicketForm是构造函数)
- 通过两种方法创建和更新 CSS
- javascript基对象,用不同的方法创建另外两个对象
- 为命名空间上公开的方法创建类型定义
- 尝试理解 JavaScript 中的对象和方法创建
- Meteor Braintree -- 通过 Meteor 方法创建客户端令牌
- 为嵌套在对象深处的方法创建别名
- 如何使用getter和setter方法创建一个Angular工厂而不遇到竞争条件
- 我们可以在 JavaScript 中使用 eval 方法创建 HTML 标签吗?
- 如何从原型方法创建对象的实例
- 为什么谷歌在其Javascript代码中为方法创建缩写
- 使用推送方法创建数组
- 如何访问使用jquery insertAfter方法创建的元素
- 如何通过objx的collect()方法创建json字符串特定字段的数组
- 如何从通过createHTMLDocument方法创建的文档中提取样式表
- 如何使用post方法创建重定向链接
- jQuery无法识别由.html()方法创建的选择器
- 为什么JavaScript中的顶级函数是作为window的方法创建的
- Javascript:通过不同的方法创建字符串
- 用方法创建javascript对象
- 在Javascript中使用Google calendar API插入方法创建新日历会返回错误400 "Mis