具有文档参数的自执行匿名函数

4
我将尝试解释以下两个概念的区别:
(function(document) {
    //do stuff with document
})(document);

并且

(function() {
    //do stuff with document
})();

我不确定为什么传递到函数中的约定似乎是使用 document ,有时也会传递 window ? 这与范围有关吗?
3个回答

6
这在使用像UglifyJS这样的压缩/混淆器时特别有用。它可以将document替换为例如a,从而使您的代码更短。

因此,代码可能会变成类似以下的形式:

(function(document, window){
  var body = document.body;
  var foo = document.querySelector('foo');
  var bar = document.querySelector('bar');
})(document, window);

变得

(function(a, b){
  var c = a.body;
  var d = a.querySelector('foo');
  var e = a.querySelector('bar');
})(document, window);

如果您未在函数中放置文档和窗口,它将只会持续显示文档;

(function(){
  var c = document.body;
  var d = document.querySelector('foo');
  var e = document.querySelector('bar');
})();

但如果您不放置任何文档,那么它不是更短吗? - Mahi
1
()比(a)短。 - victor175
@victor175 是的,这也是我问他的。 - Mahi
2
是的,但如果您在JS文件中多次使用“document”,它最终会变得更短。 - Erik Terwan
哈哈,这个简短的例子并没有阐明你的观点。实际上,多次使用相同的内容可以节省字符。 - arhak
1
哈哈,只需要一行代码,这并不重要,我已经编辑了我的答案。 - Erik Terwan

2

立即执行函数表达式(IIFE)创建一个新的局部作用域。就像任何函数一样,在调用它时可以传入参数。在JavaScript web api中,documentwindow是全局变量,并且在浏览器中运行js时可用。通过将它们传递给IIFE,您可以根据作用域访问它们为所欲为。例如:

(function(w, d) {
  console.log(w); // window
  console.log(d); // document
})(window, document);

console.log(w); // Uncaught ReferenceError: w is not defined
console.log(a); // Uncaught ReferenceError: a is not defined

第二组console.log中未定义wa的原因是它们被限定在IIFE的局部作用域内。


1
为什么我想要它们在本地作用域中? - tommyd456
作用域是一种非常重要的编程范式。它可以防止命名冲突和意外行为。 - Nick Salloum

1

这是一些原因:

1. 使用更少的全局变量 通过将函数注入全局变量,它只依赖于参数而不是可能被多次使用的全局变量。

2. 创建本地作用域 IIFE 是通过声明一个函数并立即调用它来创建新作用域的一种方式。有关更多信息,请参见 this question

3. 更好的压缩

例如,如果您将压缩示例,则会从此更改:

(function(document) {
    //do stuff with document
})(document);

To this:

(function(a) {
    //do stuff with a
})(document);

请注意,a比您的document短。 编辑:修正了拼写错误

有用的链接。我发现这个链接可以回答我的问题:“使用IIFE的性能好处在于能够将常用的全局对象(如window、document等)作为参数传递,从而减少范围查找。(记住JavaScript会在本地范围内查找属性,并一直向上链到全局范围)。因此,在本地范围内访问全局对象会减少查找时间,如下所示。” - tommyd456

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接