当我像这样在 JavaScript 中创建匿名函数时:
(function(){
/* some code here */
})()
该函数将添加到哪个对象中,该函数将存在于何处?
您还可以在 jQuery 源代码中看到这样的匿名函数:
(function(window, undefined){
/* some code here */
})(window)
这个函数的参数如何将它与匿名的 0-arg 函数区分开来?
当我像这样在 JavaScript 中创建匿名函数时:
(function(){
/* some code here */
})()
该函数将添加到哪个对象中,该函数将存在于何处?
您还可以在 jQuery 源代码中看到这样的匿名函数:
(function(window, undefined){
/* some code here */
})(window)
这个函数的参数如何将它与匿名的 0-arg 函数区分开来?
JavaScript 中的函数是值。也就是说,函数由对象表示,并且与任何其他对象一样,它可以是变量的值或参与表达式。
因此
(function() { ... })
是一个值,就像17
or"hello world"
是一个值一样。
当一个函数(作为一个值)出现在一个表达式中,并且它后面是(...)
一个括号之间以逗号分隔的表达式列表时,这就是一个函数调用。
好的,所以:
(function() { ... })()
创建一个函数(作为一个值),然后不带参数调用该函数。函数对象,至少作为该代码的直接结果,不存储在任何地方。它在函数调用完成后基本上消失了,并且该子表达式的整体值将是函数返回的任何值。
将参数传递给这样的函数与将参数传递给任何其他函数没有什么不同。在您引用的具体示例中,目的是防止由错误的“外星人”代码引起的某些异常。你的例子真的应该是:
(function(window, undefined) {
// code
})(this);
该符号this
是保留字,其值完全受运行时控制。(好吧,它在本地执行上下文中的值因此受到控制。)在全局范围内评估时,上面的代码确保在匿名函数内部,符号“窗口”将是对全局上下文的引用。这种结构对于可能在浏览器以外的上下文中使用的代码也很有用,例如 Node.js,其中全局上下文不称为“窗口”。
根据维基百科定义的第一行,您给出的两个示例都是匿名函数:
匿名函数 [...] 是定义的函数(或子例程),并且可能被调用,但未绑定到标识符
这些论点对匿名性没有影响。匿名函数可以接受 0, 1, 2, ... n 个参数,就像非匿名函数(即命名函数)一样。
匿名函数的一个主要优点是它们不必存在于任何地方——它们可以内联定义和使用,就像其他类型的其他值一样。
添加到@Pointy 的答案中,将参数添加到匿名函数没有任何区别
(function(){
/* some code here */
})()
(function(window,undefined){
/* some code here */
})(window)
这两个函数在调用后都丢失了,唯一的区别是在第二个函数内部,一些变量或函数存储在窗口上下文中,但匿名函数本身在调用后丢失了。
如果您需要保留对函数的引用,请尝试
(window.myFunc = function(arg1, arg2, arg3) {
/* your code here*/
})(arg1, arg2, arg3)