var 、let 、const 总结

var、let 用于声明变量,const 用于声明常量。都可以在一个语句中声明多个变量,变量以英文逗号分开。

var name1 = "Lee1",
    age1 = 26,
    job1 = "teacher1";

let name2 = "Lee2",
    age2 = 26,
    job2 = "teacher2";

const name3 = "Lee3",
      age3 = 26,
      job3 = "teacher3";

console.log(name1,age1,job1);
console.log(name2,age2,job2);
console.log(name3,age3,job3);

输出: 

1、var关键字

存在变量提升:var 声明的函数及变量的声明都将被提升到函数的最顶部;变量可以先使用再声明,但变量的值并不会提升。

console.log(num)//undefined
var num=20;

  这里输出 num 为 undefined:1、因为变量提升,所以并不会报错 (ReferenceError);2、因为变量的值不会提升,所以输出的是默认值undefined。

 

2、let关键字

 

1)使用let关键字声明的变量具有块级作用域:由 { } 包括,if语句和for语句里面的{ }也属于块作用域,for循环中( ) 中用let 声明的变量与此for循环绑定,在for循环外访问不到。

for(let i=0;i<2;i++){
    console.log(i);
  }
  console.log("----")
  console.log(i);

输出:

2)使用let关键字声明的变量不存在变量提升

console.log(n);
   let n=10;

输出:

3)使用let关键字声明的变量具有暂时性死区特性:在块级作用域内声明变量,这个变量会和这个块级作用域绑定

var num=10; 
if(true){ 
    console.log(num); //这里会报错, 
    //因为在块级作用域声明变量,这个变量会和这个块级作用域绑定,这里与外面的num无关了。 
    let num =20; 
}

输出:

4)不允许重复声明:let 不允许在相同作用域内重复声明同一个变量。

function foo(){
    let a=0;
    var a=1;
}
foo();

输出:​ 

 

3、const关键字

作用:声明常量(内存地址不能变化的量)。

1)具有块级作用域

2)不存在变量提升

3)具有暂时性死区特性。

4)声明常量必须赋值。

5)常量赋值后,值不能更改。——对于复杂类型数据,它内部的值是可以更改的,但是不能对它重新赋值,即数据值本身不能更改,因为重新赋值更改了该数据的内存地址。

 const num=20;
   num=10;
   console.log(num);

输出:

const obj={
       name:'刘亦菲',
       age:18
   }
   obj.name='赵灵儿'
   console.log(obj);

   obj={
       name:'李逍遥',
       age:21
   }
   console.log('------');
   console.log(obj);

输出:

这里的‘------’都未输出,是因为到 obj 赋新值时就报错了。

6)如果存储的关键字不需要变化,尽量使用 const 关键字,比如函数定义等。因为 const 关键字声明的值不需要变化,JavaScript 解析引擎不需要实时监控值的变化,所以 const 比 let 效率高。

总结:

var

let

const

函数级作用域

块级作用域

块级作用域

变量提升

不存在变量提升

不存在变量提升

值可更改

值可更改

值不可更改

没有暂时性死区特性 具有暂时性死区特性 具有暂时性死区特性
声明时不必赋值 声明时不必赋值 声明时必须赋值

经典面试题

var arr=[] 
for(var i=0;i<2;i++){ 
    arr[i]=function(){ 
        console.log(i); 
    }
} 
arr[0](); //2 
arr[1](); //2

分析:在函数内部没有定义变量 i,函数执行时在自己的作用域找不到变量 i 值,根据作用域链查找原则,要向上一层作用域查找,这里的上一层作用域就是全局作用域,有i。函数执行时,循环早已结束,所以 i 的值是不满足循环条件的值,即 i = 2,所以函数执行输出的是2。

let arr=[] 
for(let i=0;i<2;i++){ 
    arr[i]=function(){ 
        console.log(i); 
    } 
} 
arr[0](); //0 
arr[1](); //1

分析:每次循环都会产生一个块级作用域,每个块级作用域中的变量都不同,函数执行时输出的是自己上一级(循环产生的块级作用域)作用域下的 i 值。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章