我对JavaScript还比较陌生,正在自学中。目前我正在创建和调整GreaseMonkey脚本。我注意到大多数简单的脚本(即那些不需要命名函数的脚本)直接进入主代码,但有些脚本则像这样设置:
(function() {
//main code here
})();
这种编码方式有什么意义?我已经注释了顶部和底部,但脚本仍然完全相同。
这只是一种编码标准,还是实际上有一个功能?正如我的标题所问的那样,这是特定于GreaseMonkey的东西,还是我应该始终这样做的东西?
我对JavaScript还比较陌生,正在自学中。目前我正在创建和调整GreaseMonkey脚本。我注意到大多数简单的脚本(即那些不需要命名函数的脚本)直接进入主代码,但有些脚本则像这样设置:
(function() {
//main code here
})();
(function() {
var a = 5;
})();
这种方式对全局命名空间没有影响(a
变量被闭包捕获,所以window.a
不会受到影响)。这是一种非常好的方法,可以避免许多脚本互相干扰全局变量,使它们完全不是全局的。我在编写任何JavaScript时都经常使用这种技术,而不仅仅是Greasemonkey脚本,并强烈建议将其作为编写库的最佳实践。
如果您想将某些函数公开给其他JavaScript代码,而不是完全隔离您的脚本,可以像这样操作:
var MyNamespace = (function () {
var that = {};
that.square = function(x) {
return x*x;
};
return that;
})();
然后您可以在另一个脚本中输入MyNamespace.square(5)
,这将返回25。
这是一个自执行的匿名函数。
通常用于改变作用域,所有在此声明的变量和函数将在匿名函数的作用域中而不是全局(window)作用域中。
它将对象/变量保持在匿名函数范围内。这很重要,因为您可能有几个脚本文件都可能共享相同的变量名称。如果他们这样做了,他们就可能替换变量值并真正破坏您的应用程序。
行末的 ()
调用了声明的函数。换句话说,您在第一组括号中创建的匿名函数可以自动调用。除非将其分配给变量,否则没有其他方法来调用它。这避免了在内存中创建变量,并仅在运行时调用函数。
对于那些从未听说过闭包这个词的人,这里是答案:
假设我们有一个函数
function sayHi() { alert('Hello'); }
sayHi();
alert('Sup');
function() {alert('Hello'); }
3 + 1;
alert('Peace');
第二行是完全有效的。当然,第二行在您的页面上不会真正执行任何操作,就像第三行不执行任何操作一样。这被称为匿名函数。现在,就像我们可以将变量分配给第三行一样:
result = 3 + 1;
myFunc = function() { alert('Hello'); };
我们可以像之前的sayHi()函数一样使用myFunc作为函数来调用它。我们调用它的方式与调用sayHi()一样。
sayHi();
myFunc();
现在由于JavaScript被编写成具有多功能性,例如[0, 1, 2].indexOf(1)这样的东西是可行的,我们可以做如下操作:
func = function() { alert('hello'); };
func();
(function() { alert('hello'); })();
第1行和第2行将完成与第3行相同的操作,因为第3行只是第1行和第2行的扩展版本。第3行的优点在于,如果代码中后来有人使用了一个func变量,它不会对你自己的代码造成问题,此外,在第3行的函数中声明的任何变量(使用var关键字)都不会是你函数之外的有效变量,这就是闭包。
好了,这个微型教程就到这里了,希望能对你有所帮助。