我正在寻找使用对象创建命名空间和自行执行匿名函数。哪一个被认为是更好的选择?
使用对象,是否有足够的名称'myAppName'来防止冲突?
var myAppName = {
val1: "abc",
val2: "xyz",
myFunc1: function() {
return this.val2;
}
}
console.log(myAppName.val1); // abc
console.log(myAppName.myFunc1()); // xyz
使用自执行匿名函数:
(function () {
val1 = "abc";
var val2 = "xyz";
myFunc1 = function() {
return val1;
}
var myFunc2 = function() {
return val2;
}
})();
console.log(val1); // abc
console.log(myFunc1()); // abc
console.log(myFunc2()); // xyz
在上面的自执行功能代码中,它们似乎都在执行。在变量和函数名之前是否有使用和不使用var的含义?我不太清楚。有没有办法让变量和函数变得私有和公开?或者自执行功能中的所有内容都是私有的?
如果我在自执行功能之前使用'var'会发生什么?
var myAppName = (function () {
val1 = "abc";
var val2 = "xyz";
myFunc1 = function() {
return val1;
}
var myFunc2 = function() {
return val2;
}
})();
答案 0 :(得分:4)
我的第一个答案试图解决您的原始问题,并展示如何设置命名空间。我决定在第一个答案中添加第二个答案来解决您的评论中的问题,而不是添加到答案中。
全局变量实际上是window
对象的属性。如果在函数外部使用var
,则定义全局变量。如果在函数内使用var
,则表示您正在定义局部变量。如果您引用变量someValue
而未使用var
声明,则与引用window.someValue
相同。
以下代码显示了设置全局变量的不同方法,以及定义局部变量的一种方法。
window.global1 = 'abc';
global2 = 'def';
var global3 = "ghi";
(function() {
window.global4 = 'jkl';
global5 = 'mno';
var local1 = 'xyz';
})();
console.log(global1); // 'abc'
console.log(global2); // 'def'
console.log(global3); // 'ghi'
console.log(global4); // 'jkl'
console.log(global5); // 'mno'
console.log(local1); // ReferenceError: local1 is not defined
通常,您希望限制设置全局变量(至少在创建JavaScript库时)。命名空间基本上只是一个全局变量。当您将其他所有内容放在该命名空间下时,您只添加了一个全局变量。
我认为避免设置上面的global2
和global5
等全局变量也是最佳做法。相反,您应该使用函数的var
oustide(例如global3
)或在window
对象上设置属性(例如global1
和global4
)。< / p>
从我的其他答案中借用代码示例,我们可以创建一个这样的命名空间:
var myApp = (function() {
var privateValue = 'abc'; // Don't forget "var" here.
function privateFunction() {
return privateValue;
}
return {
publicValue: 'xyz',
publicFunction: function() {
return privateFunction();
}
}
})();
我们可以通过以下方式实现同样目标,但我认为这种不好的风格:
(function() {
var privateValue = 'abc'; // Don't forget "var" here.
function privateFunction() {
return privateValue;
}
myApp = {
publicValue: 'xyz',
publicFunction: function() {
return privateFunction();
}
}
})();
在这两种情况下,我们都设置了myApp
全局变量,但我认为前者比后者更清晰。
为了清楚起见,在这两种情况下,我们都将公共变量称为myApp.publicValue
并使用myApp.publicFunction()
调用公共函数,并且在匿名函数之外我们将无法引用{{ 1}}或privateValue
。
答案 1 :(得分:3)
将所有代码放在单个命名空间下肯定会有助于避免名称冲突。如果确实发生了冲突,那么更改代码来处理它就会容易得多。
如果所有内容都需要公开,那么您的第一个代码示例就可以了。如果你想要一些私有的东西,使用一个匿名的,立即执行的函数,如下所示:
var myApp = (function() {
var privateValue = 'abc'; // Don't forget "var" here.
function privateFunction() {
return privateValue;
}
return {
publicValue: 'xyz',
publicFunction: function() {
return privateFunction();
}
}
})();
注意匿名函数如何返回包含公共变量和函数的对象。如果你没有在“privateValue”之前加上“var”,那么你就没有定义一个局部变量;相反,您正在引用一个全局变量(它实际上是“窗口”对象的属性。)
如果您使用的是jQuery,我建议您使用以下内容:
(function(window, $, undefined) {
var myApp = (function() {
var privateValue = 'abc'; // Don't forget "var" here.
function privateFunction() {
return privateValue;
}
return {
publicValue: 'xyz',
publicFunction: function() {
return privateFunction();
}
}
})();
// Put myApp in the global scope.
window.myApp = myApp;
})(window, jQuery);
这样,您可以安全地使用$()
代替jQuery()
。将undefined
视为常量也是安全的。您还可以更轻松地处理某人覆盖窗口对象的情况。