我知道什么是自执行匿名函数,但我不清楚何时使用以及为什么要使用。这可能是因为我经常使用jQuery。请提供一些好的使用案例。
我知道什么是自执行匿名函数,但我不清楚何时使用以及为什么要使用。这可能是因为我经常使用jQuery。请提供一些好的使用案例。
基本上,一个自执行的匿名函数(更准确地说是即时调用函数表达式或IIFE)与声明一个命名函数然后立即调用它相同。与命名函数的唯一区别在于IIFE没有名称,因此只能在原地执行(不能从其他地方调用),因此不会向当前命名空间添加名称。
因此,您可以在任何需要将大量代码放在函数内并且该代码仅需要在当前定义的上下文中调用时使用。
以下是一些常见的使用场景:
在涉及一些本地变量和一些异步操作(ajax、timeout等)的任何类型的循环中,在异步完成函数中希望为每个循环迭代单独访问这些本地变量。
封装某些顶级代码,其具有自己的作用域和私有且与全局命名空间分离的本地变量,仅运行一次。
出于任何原因创建一个未命名的函数范围。
示例:
循环索引(针对每个setTimeout()
调用单独冻结循环索引):
for (var i = 0; i < max; i++) {
// capture the loop index into in a closure
(function(index) {
setTimeout(function() {
console.log(index);
}, 2000);
})(i);
}
顶级代码封装(创建私有但持久的变量,不在全局范围内):
(function() {
var cntr = 0;
window.getUniqueId = function() {
return ++cntr;
};
})();
在代码中创建本地可用的缩写变量,否则这些变量将处于顶层作用域。function Dictionary(initialData) {
// call parent constructor
Set.apply(this, arguments);
}
(function() {
// inherit from Set
var proto = Dictionary.prototype = new Set();
var base = Set.prototype;
// Set constructor back to us
proto.constructor = Dictionary;
// override of the base class .add()
// add(key, value)
// add(Dictionary)
// add({key1: value1, key2: value2})
proto.add = function(arg1, arg2) {
if (arg1 instanceof Set) {
// call base class to just add another Set
base.add.call(this, arg1);
} else if (typeof arg1 === "object") {
// cycle through the object and add all properties/values to the Set
for (var prop in arg1) {
if (arg1.hasOwnProperty(prop)) {
this._add(prop, arg1[prop]);
}
}
} else if (typeof arg2 !== "undefined") {
// must be add(key, value)
this._add(arg1, arg2);
}
return this;
}
proto.get = function(key) {
return this.data[key];
}
// See rest of code here: https://github.com/jfriend00/Javascript-Set/blob/master/dictionary.js
})();
map
或 filter
,也会出现相同的情况。 - zerkms你所指的是IIFE。
它有几种常见的用法:
(function() {
var foo = 123;
$(".pop-up-trigger").click(function() {
// ...
});
}());
在 JavaScript 中创建“私有变量”。通过声明一些本地变量,然后返回一些函数,这些函数可以访问这些本地变量(分配它们或获取值)。在 IIFE 外部,没有代码可以触及这些本地变量,因此它们是私有的。
创建作用域。JavaScript 没有块级作用域,只有函数作用域,因此通过拥有一个函数并调用它,就会创建一个新的作用域。