引言
要理解闭包,首先要理解作用域,js语法中分两种变量:全局变量和局部变量(函数变量)
var a = 1;function f1(c){console.log(b); // undefinedvar b = 2;console.log(a); // 1console.log(b); // 2console.log(c); // 3}f1(3);console.log(a); // 1// console.log(c); // error// console.log(b); // error
此时 a 定义在全局作用域,是全局变量,该文件中任何位置都能访问到这个变量,因为 a 会作变量提升
此时 b 定义在函数内部,c也定义在函数内部,均为局部变量,只在函数内部可以使用,也只作函数内部的变量提升
注意:如果在函数内部不使用 var 声明变量,默认其为全局变量
闭包解决了什么问题?
如何从外部访问局部变量,你可能会想到使用一个变量去承接局部变量的值,如
var a;function f1(){var b = 2;a = b;}f1();console.log(a); // 2
但是,这归根到底不是那个局部变量,而非我们想访问的变量,闭包就是为了解决这一问题而生的
function f1(){var b = 2;return function f2() {return b;}}console.log(f1()()); // b
由此看出:闭包就是在函数内部返回一个函数,即函数的嵌套。
因为函数 f2 的存在 依赖 f1,所以函数 f1 此时不能被回收,也存在于内存中。
闭包带来的问题
1 闭包使得函数被保存在内存中,内存消耗很大,所以不能滥用
2 函数本身是对象,内部变量相当于它的私有属性,所以这是不安全的
思考题
题一
var name = "The Window";var object = {name : "My Object",getNameFunc : function(){console.log(this.name);return function(){console.log(this.name);return this.name;};}};console.log(this.name); // undefinedconsole.log(name); // The Windowconsole.log(object.getNameFunc()());
题二
var name = "The Window";var object = {name : "My Object",getNameFunc : function(){var that = this;return function(){return that.name;};}};console.log(object.getNameFunc()());
上面两题,考验this以及闭包的运行机制
(结束)