闭包
闭包就是(在外部?)引用特定的局部变量实例的功能;
闭包是函数和声明该函数的词法环境的组合,这个环境包含了这个闭包创建时所能访问的所有局部变量。——MDN
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
闭包是指有权访问另一个函数作用域中的变量的函数。——《js高级程序设计第三版》
一般在js
中,闭包用来在外部访问某一函数中的局部变量,该局部变量被保存在一个内部函数块中;如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function makeAdder(x) { return function(y) { return x + y; }; }
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2)); console.log(add10(2));
|
使用场景
- 通常使用只有一个方法的对象的地方,都可以使用闭包;(将数据与函数进行绑定的时候)
闭包很有用,因为他允许将函数与其所操作的某些数据(环境)关联起来。这显然类似于面向对象编程。在面向对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。——MDN
1 2 3 4 5 6 7 8 9 10 11 12 13
| function makeSizer(size) { return function() { document.body.style.fontSize = size + 'px'; }; }
var size12 = makeSizer(12); var size14 = makeSizer(14); var size16 = makeSizer(16);
document.getElementById('size-12').onclick = size12; document.getElementById('size-14').onclick = size14; document.getElementById('size-16').onclick = size16;
|
- 模拟私有方法:即只有实例才能使用的方法,且不能直接修改对象的方法!(对比将方法绑定到
this
对象或原型prototype
上,那样可以通过直接修改对象方法从而影响所有的实例!此谓之私有?)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| 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()); Counter1.increment(); Counter1.increment(); console.log(Counter1.value()); Counter1.decrement(); console.log(Counter1.value()); console.log(Counter2.value());
|
注意事项
如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响。