JavaScript的闭包和作用域
作用域相关
作用域的概念:
-
作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性。换句话说,作用域决定了代码区块中变量和其他资源的可见性;
-
作用域的类型:
-
全局作用域:
-
最外层函数和在最外层函数外面定义的变量拥有全局作用域;
-
所有末定义直接赋值的变量自动声明为拥有全局作用域;
-
所有 window 对象的属性拥有全局作用域;
-
-
函数作用域:
-
在函数内部的作用域
-
-
块级作用域:
-
在花括号{}内部的作用域;
-
注意:
-
①对象的{}不属于块级作用域,像for(){},if(){},else{},try{},cath(){}等等的花括号才是块级作用域
-
②对象的{}的作用域是什么作用域取决于对象所处的作用域,比如对象在全局作域 下定义的,那么对象的{}的作用域就是全局作用
-
-
-
自由变量:
在当前作用域下,未定义,但使用了的变量,称为自由变量
什么是作用域链:
自由变量,会向上一层一层寻找该变量的定义,直到全局作用域还是没找到,就宣布放弃,这种一层一层的关系,就是作用域链
闭包相关
闭包的概念:
-
JavaScript中函数会产生闭包(closure)。闭包是函数本身和该函数声明时所处的环境状态的组合;
-
函数能够“记忆住”其定义时所处的环境,即使函数不在其定义的环境中被调用,也能访问定义时所处环境的变量;
-
在JavaScript中,每次创建函数时都会创建闭包
闭包的作用:
-
当闭包产生时,函数所处环境的状态会始终保持在内存中,不会在外层函数调用后被自动清除。这就是闭包的记忆性;
-
模拟私有变量,即封装对象方法
闭包的缺点:
-
不能滥用闭包,否则会造成网页的性能问题,严重时可能导致内存泄露(程序中已动态分配的内存由于某种原因未释放或无法释放)
闭包的表现形式:
闭包是作用域应用的特殊情况,有两种表现:函数作为参数被传递,函数作为返回值被返回
函数作为返回值:
1 // 函数作为返回值 2 3 function create(){ 4 let a = 100; 5 return function(){ 6 console.log(a); 7 } 8 } 9 10 let fun = create(); 11 let a = 500; 12 fun(); // 100
函数作为参数被传递:
1 function print(fun){ 2 let a = 50; 3 fun(); 4 } 5 6 let a = 362; 7 function fn(){ 8 console.log(a); 9 } 10 11 print(fn);// 362