在网上阅读其他人的源代码和各种文章时,我发现当不同的人在 JavaScript 中使用“面向对象风格”编程时,他们的做法往往截然不同。
假设,我想创建一个具有 1 个属性和 1 个函数的小模块。我至少见过 4 种方法来完成这项任务:
// Option 1
var myObject1 = {
myProp: 1,
myFunc: function () { alert("myProp has value " + this.myProp); }
};
// Option 2
var myObject2 = function () {
return {
myProp: 1,
myFunc: function () { alert("myProp has value " + this.myProp); }
};
}();
// Option 3
var MyObject3 = function () {
this.myProp = 1;
this.myFunc = function () { alert("myProp has value " + this.myProp); }
};
var myObject3 = new MyObject3();
// Option 4
var MyObject4 = function () { };
MyObject4.prototype.myProp = 1;
MyObject4.prototype.myFunc = function () { alert("myProp has value " + this.myProp); };
var myObject4 = new MyObject4();
所有这些方法在语法上都不同,但似乎生成可以以相同方式使用的对象。
它们之间的语义差异是什么?是否存在出于某种原因我应该选择其中一个选项而不是其他选项的情况?
最佳答案
myObject1
是一个对象文字(单例)。当您只想拥有一个这种类型的对象时很有用。将其视为静态对象。
myObject2
返回一个对象文字。因此,在执行 var foo = myObject2()
后,变量 foo
将保存结果 { myProp: 1, myFunc: function(){...} }
并引用已执行的父函数。这称为闭包。例如,这可用于定义公共(public) API 或模块。
即:
var foo = (function(){
var privateProp = "I am a private property";
// the object below is returned, privateProp is accessible
// only through foo.publicProp
return {
publicProp: privateProp
}
})();
现在可以通过 foo.publicProp
访问 privateProp
属性。
MyObject3
和 MyObject4
是构造函数。通过在函数调用之前使用 new
关键字,您可以告诉 JavaScript 创建该对象的实例
。这意味着以这种方式创建的每个新对象都将从对象定义继承属性和方法。
MyObject3
和 MyObject4
之间的区别在于,对于前者,该对象的每个实例都将拥有其自己的副本myProp
和 myFunc
属性,而后者只会引用这些属性。这意味着无论您创建多少个 MyObject4
对象实例,都只会有 myProp
和 myFunc
之一。
我建议您了解闭包、原型(prototype)继承和几种对象设计模式(模块等)在 JavaScript 中的工作原理。
关于JavaScript - 构造对象的不同方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36836089/