概念:
函数和对其四周状态(lexical environment,词法环境)的援用捆绑在一起形成闭包(closure)。也就是说,闭包能够让你从外部函数拜访内部函数作用域。
闭包是由函数以及申明该函数的词法环境组合而成的。 该环境蕴含了这个闭包创立时作用域内的任何局部变量。

闭包很有用,因为它容许将函数与其所操作的某些数据(环境)关联起来。这显然相似于面向对象编程。在面向对象编程中,对象容许咱们将某些数据(对象的属性)与一个或者多个办法相关联。因而,通常你应用只有一个办法的对象的中央,都能够应用闭包。

闭包的例子:

function init() {  var name = "Mozilla"; // name 是一个被 init 创立的局部变量  function displayName() { // displayName() 是外部函数,一个闭包    alert(name); // 应用了父函数中申明的变量  }  displayName();}init();
function makeFunc() {  var name = "Mozilla";  function displayName() {    alert(name);  }  return displayName;}var myFunc = makeFunc();myFunc();
function makeAdder(x) {  return function(y) {    return x + y;  };}var add5 = makeAdder(5);var add10 = makeAdder(10);console.log(add5(2)); // 7console.log(add10(2)); // 12
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;

性能考量:
如果不是某些特定工作须要应用闭包,在其它函数中创立函数是不明智的,因为闭包在处理速度和内存耗费方面对脚本性能具备负面影响。
例如,在创立新的对象或者类时,办法通常应该关联于对象的原型,而不是定义到对象的结构器中。起因是这将导致每次结构器被调用时,办法都会被从新赋值一次(也就是说,对于每个对象的创立,办法都会被从新赋值)。

function MyObject(name, message) {  this.name = name.toString();  this.getName = function() {    return this.name;  };}

应该替换为以下:

function MyObject(name, message) {  this.name = name.toString();}MyObject.prototype.getName = function() {  return this.name;};