正如 Russ Cam 所说,您可以避免污染全局命名空间,这在当今组合来自多个位置(TinyMCE 等)的脚本时非常重要。
正如 Alex Sexton 所说,这也有助于良好的代码组织。
如果您使用这种技术,我建议使用模块模式。这仍然使用对象文字,但作为作用域函数的返回值:
var MyThingy = (function() {
function doSomethingCool() {
...
}
function internalSomething() {
....
}
function anotherNiftyThing() {
// Note that within the scoping function, functions can
// call each other direct.
doSomethingCool();
internalSomething();
}
return {
doSomethingCool: doSomethingCool,
anotherNiftyThing: anotherNiftyThing
};
})();
外用:
MyThingy.doSomethingCool();
作用域函数包装了所有函数,然后立即调用它并存储其返回值。优点:
- 函数是正常声明的,因此具有names。 (而与
{name: function() { ... }}
格式,所有函数都是匿名的,即使引用它们的属性有名称。)名称帮助工具可以帮助您,从在调试器中显示调用堆栈,到告诉您哪个函数引发了异常。 (2015 年更新:最新的 JavaScript 规范,ECMAScript 第 6 版,定义了 JavaScript 引擎必须执行的大量方法infer函数的名称。其中之一是当函数被分配给一个属性时,如我们的{name: function() { ... }}
例子。因此,随着引擎实现 ES6,这个原因就会消失。)
- 让您可以自由地拥有仅供您的模块使用的私有函数(例如我的
internalSomething
多于)。页面上没有其他代码可以调用这些函数;他们确实是私人的。只有最后在 return 语句中导出的内容在作用域函数之外才可见。
- 如果实现完全改变(例如 IE-vs-W3C 的东西,或者 SVG 与 Canvas 等),则可以根据环境轻松返回不同的函数。
返回不同函数的示例:
var MyUtils = (function() {
function hookViaAttach(element, eventName, handler) {
element.attachEvent('on' + eventName, handler);
}
function hookViaListener(element, eventName, handler) {
element.addEventListener(eventName, handler, false);
}
return {
hook: window.attachEvent ? hookViaAttach : hookViaListener
};
})();
MyUtils.hook(document.getElementById('foo'), 'click', /* handler goes here */);