我遇到了代码变量名相互冲突的问题,即;
<script type="text/javascript">var a = "hello"; </script>
<script type="text/javascript">alert(a);//this works, when I want 'a' not to exist </script>
闭包是唯一的选择吗?
来自c#背景,它就像构建一个未引用的委托实例,然后将其调用为内联,这似乎有点混乱
(function(){var a = "hello";})();
(function(){alert(a);})();//yes! working as expected
答案 0 :(得分:6)
使用(立即自动执行)函数创建新范围确实是可行的方法。
这样做的另一个好处是可以确保某些变量具有特定值。使用jQuery时,以下内容很常见,例如:
(function($, window, undefined) {
// ...
})(jQuery, this);
除非你有大量的函数,每个函数只有一个语句(如你的例子),它也是完全可读的。
答案 1 :(得分:5)
是的,关闭是您唯一的选择。在浏览器中,所有JavaScript文件都放在同一个全局范围内。
IIFE's在JavaScript中是非常的常见位置;我不会称他们为凌乱。
答案 2 :(得分:2)
Javascript 只有具有功能范围,与具有块范围的C#不同。以下代码是有效的javascript和C#:
var x = 2;
while(true) {
var y = 3;
break;
}
//y is not accessible here in C#, but is in javascript
创建新范围的唯一方法是创建并执行匿名函数。
答案 3 :(得分:0)
简而言之,内联的东西,你最好使用模块模式来创建一个闭包,从而模拟私有变量。
(function(){
var a....
})();
更好的长期方法是将对象用作名称空间。
var NS = {};
NS.a = 1;
答案 4 :(得分:0)
只是提供不同的视角。可以在不使用闭包的情况下编写代码,并维护(可以说是)安全的全局变量范围。
定义一个对象,用作命名空间,具有适当的唯一名称(例如MyAppContext),它具有全局范围,如果您需要定义类似全局的变量,仅用于您的应用程序,将它们附加到此对象。
MyAppContext.appTitle ='应用标题';
在您创建MyAppContect
的脚本开头,确保它不存在。
确保所有功能范围的变量都使用var
关键字,因此您知道自己没有引用全局值。
显然,这种方法会让您忘记用var
定义一些函数变量。 JSLint可以帮助您解决这个问题。
如果我开始受到抨击,我很乐意收回这个答案,但我相信这是一种可行的替代方法来使用闭包。嘿!这是旧skool
我也同意封闭的使用更安全,但认为这可能会让你感兴趣。