js基础-作用域和作用域链以及闭包

作用域概念:
作用域:变量可访问的范围。

在 JavaScript 中, 对象和函数同样也是变量。
在 JavaScript 中, 作用域为可访问变量,对象,函数的集合。
JavaScript 函数作用域: 作用域在函数内修改。

作用域分类:
  全局作用域局部作用域

局部作用域:
  变量在函数内声明,只能在函数内部访问,即局部变量
  函数参数也是局部变量

因为局部变量只作用于函数内,所以不同的函数可以使用相同名称的变量。

全局作用域:
  变量在函数外定义,即为全局变量
  全局变量有 全局作用域: 网页中所有脚本和函数均可使用。

如果变量在函数内没有声明(没有使用 var 关键字),该变量为全局变量。

在 HTML 中, 全局变量是 window 对象: 所有数据变量都属于 window 对象。

1 var a = 100;//全局
2 function fn(){
3 var a =200;
4 console.log('函数作用域',a);
5 }
6 console.log('全局作用域',a); //全局作用域 100
7 fn();//函数作用域 200

JavaScript 变量生命周期:
JavaScript 变量生命周期在它声明时初始化。
局部变量在函数执行完毕后销毁。
全局变量在页面关闭后销毁。

js中无块级作用域

1       if(true){
2         var name = 'tml';
3       }
4       console.log(name); //tml   因为无块级作用域,不会报错

无块级作用域可能带来的影响
1)变量提示导致内部变量可能覆盖外层变量

var i = 5;
function func(){
    console.log(i);
    if(true){
        var i = 6;
    }
}
func();//undefined

2)局部变量可能泄露为全局变量

1 for(var i = 0; i < 10; i++){
2     console.log(i);
3 }
4 console.log('i',i);//10 

可通过let ,const 或闭包解决这些影响

作用域链

概念:当声明一个函数时,局部作用域一级一级向上包起来,就是作用域链

   1.函数中,变量先从局部作用域找,未找到,则去上一层局部作用域找,没有,则去全局作用域找,全局未找到,则报错;

   2.当前作用域没有定义的变量,即为‘自由变量’

    var a = 100;
    function fn(){
      var b =201;
      
      console.log('a',a);//a 自由变量

      console.log('b',b);

      console.log('c',c);
    }  
  
    fn(); 

结果:

提到作用域,就很容易想到闭包。

闭包是什么?

保护并重用局部变量的词法结构

何时使用闭包?

共享局部变量,且不希望被随便篡改时

构建闭包3步骤:

1.使用外层函数封装受保护的局部变量专门操作变量的内层函数

2.外层函数将内层函数返回(return)到外部

3.在全局调用外层函数,获得内部函数的对象,保存在全局变量中反复使用

根据闭包特点判断闭包:

 1. 嵌套函数

 2. 内层函数使用了外层函数的局部变量

 3. 内层函数对象被返回到外部,在全局反复调用

优点:闭包可以形成独立的空间,永久的保存局部变量。

缺点:1)保存中间值的状态缺点是容易造成内存泄漏,因为闭包中的局部变量永远不会被回收

            2)闭包占内存过高

 1 function F1(){
 2     var a =100;
 3 
 4     return function (){//返回一个函数(函数作为返回值)
 5       console.log(a);
 6     }
 7   }
 8   var f1 = F1();//f1得到一个函数
 9   var a =200000;
10   f1();//100
1 function addCount() {
2   var num= 0;
3   return function() {
4     num= num+ 1;
5     console.log(num);
6   };
7 }
8 var aa = addCount();//外层函数返回内层函数
9 aa();//1

结果:

原文地址:https://www.cnblogs.com/lingXie/p/11493820.html