var module = {};
(function(exports){
exports.notGlobalFunction = function() {
console.log('I am not global');
};
}(module));
function notGlobalFunction() {
console.log('I am global');
}
notGlobalFunction(); //outputs "I am global"
module.notGlobalFunction(); //outputs "I am not global"
任何人都可以帮我理解这里发生了什么吗?如果你打电话给notGlobalFunction()
,我会得到它,它只会调用第二个函数。
但是var module = {}
在做什么?为什么在第一个函数内再次调用它?
它说这通常被称为自动执行的匿名函数,但我不知道这意味着什么。
答案 0 :(得分:24)
立即调用的函数通常用于创建一个私有的本地函数作用域,不能从外部访问,并且可以定义它自己的本地符号而不影响外部世界。这通常是一种很好的做法,但在这种特殊情况下,除了几行代码之外,我没有看到它产生任何好处,因为它不用于任何东西。
这段代码:
(function(exports){
exports.notGlobalFunction = function() {
console.log('I am not global');
};
}(module));
与没有立即调用的代码相同:
module.notGlobalFunction = function() {
console.log('I am not global');
};
不同的一点是,在第一个中,创建了名为modules
的{{1}}的别名,该别名对于立即调用的功能块是本地的。但是,别名没有什么独特之处,代码也可以直接使用exports
。
变量modules
被创建为单个全局父对象,然后可以将许多其他全局变量保存为属性。这通常称为“命名空间”。这通常是一个很好的设计模式,因为它最大限度地减少了可能与同一项目/页面中使用的其他代码段冲突的顶级全局变量的数量。
所以不要像这样制作多个顶级变量:
modules
可以像这样创建一个顶级变量:
var x, y, z;
然后,将所有其他全局变量作为属性附加到它:
var modules = {};
这样,虽然仍有多个全局变量,但只有一个顶级全局变量可能与其他代码冲突。
类似地,一个立即调用的函数创建一个本地私有作用域,在该作用域中可以创建对该作用域本地的变量,并且不会干扰其他代码段:
modules.x = 5;
modules.y = 10;
modules.z = 0;
将参数传递给立即调用的函数只是将值传递给立即调用的函数的范围,该范围将具有它自己的本地符号:
(function() {
var x, y, z;
// variables x, y and z are available to any code inside this immediately invoked function
// and they act like global variables inside this function block and
// there values will persist for the lifetime of the program
// But, they are not truly global and will not interfere with any other global
// variables and cannot be accessed by code outside this block.
// They create both privacy and isolation, yet work just as well
})();
答案 1 :(得分:2)
这将创建一个新的空对象:
var module = {};
它与:
相同var module = new Object();
这个包装器:
(function(exports){
...
}(module));
只完成在函数内添加变量module
的别名。由于匿名函数中没有局部变量或函数,没有它就可以这样做:
module.notGlobalFunction = function() {
console.log('I am not global');
};
这样的匿名函数可以用来创建一个私有变量:
(function(exports){
var s = 'I am not global';
exports.notGlobalFunction = function() {
console.log(s);
};
}(module));
现在添加到notGlobalFunction
对象的方法module
可以访问变量s
,但没有其他代码可以访问它。
答案 2 :(得分:0)
“自我执行”可能会产生误导。它是一个匿名函数表达式,它没有被赋值或作为参数给出,而是被调用。请阅读Immediately-Invoked Function Expression (IIFE)。
什么是var module = {}在做什么?
它初始化一个充当命名空间的空对象。
为什么在第一个函数内再次调用它?
它不是“被叫”,而不是“内部”第一个功能。该对象作为参数(“exports”)提供给IEFE,并且内部有一个分配给它的属性。
答案 3 :(得分:0)
IIFE正在向作为参数传入的module
对象添加方法。代码演示了函数创建范围。具有相同名称的方法将被添加到对象和浏览器的头对象(窗口)中。