Javascript之闭包

Posted by Shen Chaoran on June 29, 2018

闭包

在一些编程语言中,函数中的局部变量仅在函数的执行期间可用。但是在 js 中使用闭包并非如此。 闭包是由函数以及创建该函数的词法环境组合而成。这个环境包含了这个闭包创建时所能访问的所有局部变量。

function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}

var add5 = makeAdder(5);
var add10 = makeAdder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12

实用的闭包

闭包很有用,因为它允许将函数与其所操作的某些数据(环境)关联起来。这显然类似于面向对象编程。在面向对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。因此,通常你使用只有一个方法的对象的地方,都可以使用闭包

使用闭包模拟私有属性和方法

var makeCounter = function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }  
};

var Counter1 = makeCounter();
var Counter2 = makeCounter();
console.log(Counter1.value()); /* logs 0 */
Counter1.increment();
Counter1.increment();
console.log(Counter1.value()); /* logs 2 */
Counter1.decrement();
console.log(Counter1.value()); /* logs 1 */
console.log(Counter2.value()); /* logs 0 */

在循环中使用闭包

for (var i = 1; i <= 5; i++) {
    setTimeout(function(){
		console.log(i)  // 5 5 5 5 5
    }, i * 1000);
}
for (var i = 1; i <= 5; i++) {
    // 避免过多地使用闭包,可以使用 let (块及作用域)
    let v = i;
    setTimeout(function(){
		console.log(v)  // 1 2 3 4 5
    }, i * 1000);
}
var logV = function(v) {
	return () => {
		console.log(v)
	}
}
for (var i = 1; i <= 5; i++) {
    setTimeout(logV(i), i * 1000);
}

参考