Coding style JS库的这种模式有什么问题吗?
诚然,我对javascript的内部工作原理知之甚少,但我需要创建一个库,并希望学习(因此在这里提问)。我理解使用闭包和导出到窗口不会污染全局名称空间,但除此之外,它让我有点困惑Coding style JS库的这种模式有什么问题吗?,coding-style,javascript,Coding Style,Javascript,诚然,我对javascript的内部工作原理知之甚少,但我需要创建一个库,并希望学习(因此在这里提问)。我理解使用闭包和导出到窗口不会污染全局名称空间,但除此之外,它让我有点困惑 (function() { var Drop = window.Drop = function() { var files = []; var add = function(word) { files.push(word);
(function() {
var Drop = window.Drop = function() {
var files = [];
var add = function(word) {
files.push(word);
return files;
}
return {
files: files,
add: add
}
}
})()
// All of these seem to be the same?
var a = Drop();
var b = new Drop();
var c = new Drop;
// Each has their own state which is what I want.
a.add("file1");
b.add("file2");
c.add("file3");
- 为什么三种“初始化”方法都是相同的李>
- 到底是什么让他们有能力拥有自己的国家李>
- 是否有替代返回语法的方法在Drop上导出这些函数
- 有没有更好的最佳实践方法来创建这样一个自包含的库
Drop()
)只是正常调用函数,因此此
是全局对象(浏览器环境中的窗口
)。它完成它的工作,然后返回一个对象,正如您所期望的那样
第二种方法(new Drop()
)创建一个新的Drop
对象,并在this
设置为该对象的情况下执行构造函数。但是,您不会在任何地方使用this
并返回从对象文本创建的对象,因此Drop
对象将被丢弃,而返回对象文本
第三种方式(newdrop
)在语义上与第二种相同;这只是句法上的不同Drop
,它都有自己的一组局部变量,不同于任何其他调用Drop
的局部变量新的语法和原型。这有几个优点:即,只需创建一次add
函数,而不是为每个Drop
调用创建一个函数。修改后的代码可能如下所示:
function Drop() {
this.files = [];
}
Drop.prototype.add = function(word) {
this.files.push(word);
return this.files;
};
但是,这样做会使您无法在没有new
的情况下调用它。但是,有一个解决方法:您可以将其添加为函数下拉列表中的第一行:
if(!(this instanceof Drop)) {
return new Drop();
}
因为当你用new
调用它时,这个
将是一个Drop
,而当你不用new
调用它时,这个
将不是一个Drop
,你可以看到这个
是否是一个Drop
,如果是,继续初始化;否则,请使用new
重新调用它
还有另一个语义差异。考虑下面的代码:
var drop = new Drop();
var adder = drop.add;
adder(someFile);
您的代码将在这里工作。基于原型的代码不会,因为此
将是全局对象,而不是drop
。这也有一个解决方法:在构造函数中的某个地方,您可以执行以下操作:
this.add = this.add.bind(this);
当然,如果库的使用者不打算从对象中提取函数,则不需要这样做。此外,您可能需要为没有Function.prototype.bind的浏览器填充Function.prototype.bind
- 为什么三种“初始化”方法都是相同的
new
调用函数时,函数中的this
值将成为新对象
但在您的案例中,它们相同的原因是您根本没有使用此
。您正在使用对象文字语法创建一个单独的对象,并返回它,因此new
没有影响
- 到底是什么让他们有能力拥有自己的国家
Drop
调用中重新创建,因此在封闭变量范围上创建闭包。因此,每个调用的文件
数组可以被每个调用中的函数连续访问
- 是否有替代返回语法的方法在Drop上导出这些函数
this
,并删除return
语句。但这需要使用new
。或者,将函数放在Drop
的.prototype
对象上,它们将在使用new
创建的所有实例中共享,但将分配给此
的数组保留在构造函数中,以便不共享
对于引用数组的原型函数,它们将使用this.files
- 有没有更好的最佳实践方法来创建这样一个自包含的库
这是一个完整的原型继承版本。另外,没有使用外部的
(function(){})(
,因此我将添加一个变量来利用它
(function() {
var totalObjects = 0; // visible only to functions created in this scope
var Drop = window.Drop = function() {
this.files = [];
this.serialNumber = totalObjects++;
}
Drop.prototype.add = function(word) {
this.files.push(word);
return this.files;
};
})();
您可能想了解“javascript闭包”。
(function() {
var totalObjects = 0; // visible only to functions created in this scope
var Drop = window.Drop = function() {
this.files = [];
this.serialNumber = totalObjects++;
}
Drop.prototype.add = function(word) {
this.files.push(word);
return this.files;
};
})();