在 JavaScript 中,闭包是一种特殊的函数,它可以访问在它创建时外部作用域的变量和参数,即使这些变量和参数在函数调用时已经不存在了。
简单来说,闭包就是“函数和函数所能够访问的外部变量的一个共同体”。
在 JavaScript 中,每次创建一个函数,都会同时创建一个作用域链(scope chain)。作用域链的作用是保存自由变量(free variable)的引用,自由变量指的是既不是函数参数也不是局部变量的变量。当函数执行时,函数会通过作用域链(向上遍历与创建该函数的作用域链相同的作用域链)访问自由变量,这就形成了闭包。
闭包可以用于实现一些高级的,具有固定状态的功能,如函数柯里化(function currying)和模块化(module pattern)等。
在这个示例中,我们创建了一个函数,这个函数可以让我们创建多个计数器。每个计数器都是独立的,可以独立递增、递减。
function createCounter() {
var count = 0;
return {
increment: function () {
count++;
},
decrement: function () {
count--;
},
getCount: function () {
return count;
}
}
}
var counter1 = createCounter();
var counter2 = createCounter();
console.log(counter1.getCount()); // 0
console.log(counter2.getCount()); // 0
counter1.increment();
counter1.increment();
console.log(counter1.getCount()); // 2
console.log(counter2.getCount()); // 0
counter2.decrement();
console.log(counter1.getCount()); // 2
console.log(counter2.getCount()); // -1
在这个示例中,createCounter() 是一个函数,它返回一个对象,这个对象包含三个方法。每个对象都包含一个局部变量 count,这个变量只能通过对象内部的方法访问。这个局部变量被保存在 createCounter() 函数的作用域链中,因为对象内部的方法可以访问它,所以每个对象都有一个独立的 count。
函数柯里化(function currying)是什么意思?指的是把接受多个参数的函数转换成接受一个单一参数(最初函数的第一个参数)的函数,并返回接受余下的参数,并且返回结果的新函数的技术。
示例代码:
function add(a, b) {
return a + b;
}
function curry(fn) {
var args = Array.prototype.slice.call(arguments, 1);
return function () {
var innerArgs = Array.prototype.slice.call(arguments);
var finalArgs = args.concat(innerArgs);
return fn.apply(null, finalArgs);
};
}
var add10 = curry(add, 10);
console.log(add10(5)); // 15
console.log(add10(10)); // 20
在这个示例中,我们创建了一个函数 curry(),这个函数接受一个函数 fn,然后返回一个新的函数,这个新函数可以接受一个或多个参数。curry() 函数采用了类似“闭包”的形式,它保存了原函数的第一个参数,并在返回的新函数中使用。
闭包是 JavaScript 强大的特性之一,它可以让我们实现很多高级的功能。但是,在使用闭包的时候,我们也要注意一些问题,比如内存泄漏等。所以,在使用闭包之前一定要了解它的运作原理和注意事项。
本文链接:http://task.lmcjl.com/news/11755.html