变量的做用域无非就是两种:全局变量和局部变量。闭包
函数内部声明变量的时候,必定要使用var命令。若是不用的话,你实际上声明了一个全局变量!函数
有权访问另外一个函数做用域的变量,常见的建立方式就是在一个函数内部建立另外一个函数,经过另外一个函数访问这个函数的局部变量。性能
简单的说就是,闭包就是可以读取其余函数内部变量的函数。this
因为在Javascript语言中,只有函数内部的子函数才能读取局部变量,所以能够把闭包简单理解成"定义在一个函数内部的函数"。code
MDN中定义的是:对象
闭包是指可以访问自由变量的函数。换句话说,在闭包中定义的函数能够“记忆”它被建立的环境。注:自由变量是既不是在本地声明又不做为参数传递的一类变量。ip
function A(){ function B(){ console.log("Hello Closure!"); } return B; } var b = A(); b();//Hello Closure!
因此经过这个例子能够简单理解闭包。内存
* 定义一个函数A() * A中定义了函数B() * A中返回B * 执行A(),把A的返回结果赋值给变量b * 执行b()
总结一句话:函数A的内部函数B被函数A外的一个变量b引用。因此当一个内部函数被其外部函数以外的变量引用时,就造成了一个闭包资源
在一个模块中定义一个变量,但愿这个变量保存在内存中又不会污染全局变量,就用闭包来定义这个模板。作用域
它的最大用处有两个,一个是前面提到的能够读取函数内部的变量,另外一个就是让这些变量的值始终保持在内存中。
注意:可使用以后,给它加null,接触引用。
例子1:
var name = "The Window"; // 全局 var object = { name: "My Object", // 局部 getNameFunc: function () { // 对象中的方法,this指向obj这个对象 return function () { // 闭包 return this.name; // this指向window }; } }; alert(object.getNameFunc()()); // The Window
例子2:
var name = "The Window"; // 全局 var object = { name: "My Object", // 局部 getNameFunc: function () { // 对象中的方法,this指向obj这个对象 var that = this; // 将getNameFunc()的this保存在that变量中 return function () { // 闭包 return that.name; // that指向object }; } }; alert(object.getNameFunc()()); // My Object
例子3:
var name = "The Window"; // 全局 var object = { name: "My Object", // 局部 getNameFunc: function () { return function () { // 闭包 var that = this; return that.name; }; } }; alert(object.getNameFunc()()); // The Window
例子4:
var name = "The Window"; // 全局 var object = { name: "My Object", // 局部 getNameFunc: function () { // 对象中的方法,this指向obj这个对象 return function () { // 闭包 var that = this; // 将getNameFunc()的this保存在that变量中 return that.name; // this指向window }; } }; alert(object.getNameFunc().call(object)); // My Object call改变this指向