前端面试——JS变量作用域,var,let,const的区别

1.讲一下JS中的变量作用域,以及var、 let、 const三者的区别?

http://es6.ruanyifeng.com/#docs/let

(1)变量作用域

  •  ES5 :全局作用域、函数作用域,没有块作用域的概念。
  •  ES6 :全局作用域、函数作用域、块作用域,块作用域由 { } 包括,if语句和 for语句里面的{ }也属于块作用域。

(2)var、let、const三者的区别

  • var定义的变量,具有函数作用域,可以跨块访问(没有块的概念), 不能跨函数访问,存在变量提升现象,且可多次声明。
  • let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问,不存在变量提升现象,且只能声明一次。
  • const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。

(3)let的暂时性死区TDZ是什么?

       只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。ES6 明确规定,如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。

例子1:通过var定义的变量可以跨块作用域访问到,但是不能跨函数作用域访问到。

{
        var a = 1;
        console.log(a); // 输出1
    }
    console.log(a); // 输出1

    (function A() {
        var b = 2;
        console.log(b); //输出 2
    })();
    console.log(b); // 报错

例子2:var的变量提升现象,并可以声明多次。

   var a = 99;            // 全局变量a
   f();                   // f是函数,虽然定义在调用的后面,但是函数声明会提升到作用域的顶部。 
   console.log(a);        // a=>99,  此时是全局变量的a
  function f() {
     console.log(a);      // 当前的a变量是下面变量a声明提升后,默认值undefined
     var a = 10;
     console.log(a);      // a => 10
  }

// 输出结果:
undefined
10
99

例子3:let声明的变量,其声明必须要在使用之前,否则会报错Uncaught ReferenceError,即不存在变量提升,此外,let不允许在相同作用域内,重复声明同一个变量。否则报错:Uncaught SyntaxError: Identifier 'XXX' has already been declared

console.log(a);    // 错误:Uncaught ReferenceError ...
let a = 'aicoder.com';..
let a = 'b';//Uncaught SyntaxError: Identifier 'a' has already been declared

例子4:if语句和for语句属于块作用域,if语句和for语句中用var定义的变量可以在外面访问到。
    if(true) {
        var c = 3;
    }
    console.log(c); // 输出3
    for(var i = 0; i < 4; i ++) {
        var d = 5;
    };
    console.log(i); // 输出4   (循环结束i已经是4,所以此处i为4)
    console.log(d); // 输出5

例子5:块作用域
    {
        var a = 1;
        let b = 2;
        const c = 3;
        c = 4; // 报错
        var aa;
        let bb;
        const cc; // 报错,常量必须在声明时赋值
        console.log(a); // 输出1
        console.log(b); // 输出2
        console.log(c); // 输出3
        console.log(aa); // undefined
        console.log(bb); // undefined
    }
    console.log(a); // 输出1,var声明的变量可以跨块作用域访问
    console.log(b); // 报错,let声明的变量不可以跨块作用域访问
    console.log(c); // 报错,const声明的变量不可以跨块作用域访问

例子6:函数作用域,var,let和const三个关键字声明的变量都不能跨函数作用域访问

    (function A() {
        var d = 5;
        let e = 6;
        const f = 7;
        console.log(d); // 5
        console.log(e); // 6  
        console.log(f); // 7 
 
    })();
     console.log(d); // 报错
     console.log(e); // 报错
    console.log(f); // 报错

猜你喜欢

转载自blog.csdn.net/qq_21428081/article/details/82455931
今日推荐