闭包
变量作用域
- 变量作用域的概念:就是一个变量可以使用的范围
- JS中首先有一个最外层的作用域:称之为全局作用域
- JS中还可以通过函数创建出一个独立的作用域,其中函数可以嵌套,所以作用域也可以嵌套
作用域链
-
由于作用域是相对于变量而言的,而如果存在多级作用域,这个变量又来自于哪里?这个问题就需要好好地探究一下了,我们把这个变量的查找过程称之为变量的作用域链
-
简单来说,作用域链可以用以下几句话来概括:(或者说:确定一个变量来自于哪个作用域)
- 查看当前作用域,如果当前作用域声明了这个变量,就确定结果
- 查找当前作用域的上级作用域,也就是当前函数的上级函数,看看上级函数中有没有声明
- 再查找上级函数的上级函数,直到全局作用域为止
- 如果全局作用域中也没有,我们就认为这个变量未声明(xxx is not defined)
- 再查找上级函数的上级函数,直到全局作用域为止
- 查找当前作用域的上级作用域,也就是当前函数的上级函数,看看上级函数中有没有声明
- 查看当前作用域,如果当前作用域声明了这个变量,就确定结果
-
举例1:
var name="张三";
function f1(){
var name="abc";
console.log(name);
}
f1();
- 举例2:
var name="张三";
function f1(){
console.log(name);
var name="abc";
}
f1();
- 举例3:
var name="张三";
function f1(){
console.log(name);
var name="abc";
}
f1();
- 举例4:
var name="张三";
function f1(){
return function(){
console.log(name);
}
var name="abc";
}
var fn=f1();
fn();
- 举例5:
var name="张三";
function f1(){
return {
say:function(){
console.log(name);
var name="abc";
}
}
}
var fn=f1();
闭包的问题
function fn(){
var a=5;
return function(){
a++;
console.log(a);
}
}
var f1=fn();
f1();
f1();
f1();
闭包问题的产生原因
- 函数执行完毕后,作用域中保留了最新的a变量的值
闭包的应用场景
- 模块化
- 防止变量被破坏