深入理解ES6变量声明

前言

       本文适用于拥有ES5基础的读者。 本文将要介绍ES6新增的的两个变量 let 和 const。

正文

1.在ES6之前的变量声明会被提升到作用域顶端,而ES6新增的变量声明并不会被提升到作用域顶端。ES6的变量声明是块级声明
       回顾一下关键字var 声明变量,使用var声明变量,无论实际声明的位置在哪里(变量声明会被提升到作用域的顶端),都会被视为声明在所在函数的顶部。
例如:

function getValue(condition){
       if(condition){
          var value = 1;
          return value;
       }else{
          return null;
       //value 在此处可以访问,值为undefined;因为value这个变量会被提到作用域的顶端。
       }
       //value 在此处可以访问,值为undefined;因为value这个变量会被提到作用域的顶端。
}

ES6 新增的let 和 const
       let 和 const 均为块级声明,所声明的变量在指定的块级作用域(词法作用域)之外无法访问,不会把变量声明提升到作用域的顶端。

function getValue(condition){
       if(condition){
          let value = 1;
          return value;
       }else{
          return null;
       //value 此处不可访问
       }
       //value 此处不可访问
}

2.ES6之前的变量都可以重复声明,而ES6新增的变量不能重复声明。
var 可以重复声明,只不过后面的会覆盖前面的。
而 let 和 const 不可以在同一作用域里面重复声明,否则则会报错。

 var a = 1;
    var a = 10;
    // a =10
    let b = 1;
    let b = 10;
    // Uncaught SyntaxError: Identifier 'b' has already been declared
    const c = 1;
    const c = 10;
    // Uncaught SyntaxError: Identifier 'c' has already been declared

此处特别注意出现语法解析错误(SyntaxError)时,出现错误的那行之后都不会再运行下去。
在不同作用域则不会报错,会屏蔽全局变量。

 var a = 1;
    if (2 > 1) {
        let a = 2;
        // 屏蔽全局
    }

3.在ES6之前的变量声明可以修改,而ES6新增的变量声明并不能修改。
let 变量 可以修改 const 常量 不可以修改
const声明的变量被认为是常量,设置后不可修改 因此声明时需要初始化(即赋值),不初始化会报错。

const d;
//Uncaught SyntaxError: Missing initializer in const declaration

const声明的对象中的值可以修改,它本身不可以修改。

const person = {
        name = "lu",
        age = 10
}
person.age = 12;
    // age = 12
person = {
        name = "liu",
        age = 13
}
//Uncaught SyntaxError: Invalid shorthand property initializer

4.ES6之前变量未经声明可以访问,而使用ES6新增的 let 和 const 声明的变量,未经声明访问则会报错,即使使用安全的操作(typeof)。此问题称为暂时性死区

console.log(typeof value);
    // undefined
    
console.log(typeof value1);
    //  Uncaught ReferenceError: Cannot access 'value1' before initialization
    let value1 = 1;

5.var 在循环内声明变量,在循环外可以访问,因为变量会提升,而let 在循环内声明变量,在循环外不可以访问,因为它是块级变量声明,变量不会提升。

for (var i = 1; i < 10; i++) {
        console.log("123");
    }
    console.log(i);
// 10
for (let i = 1; i < 10; i++) {
        console.log("123");
    }
    console.log(i);
//Uncaught ReferenceError: i is not defined

       const 不可以在for 循环内声明变量,因为每一次循环相当于修改其值,而const 声明的变量不可修改其值,const 可以在 for in 和 for of中声明变量,因为并没有修改其值。

for (const i = 1; i < 10; i++) {
        console.log("123");
    }
    console.log(i);
//Uncaught TypeError: Assignment to constant variable.
var count = [];
object = {
     a: 2;
     b: 1;
}
for(const key in object){
    count.push(function(){
          console.log(key);
}
count.forEach(function(count){
    count();
//依次输出 2 1
}

6.循环内的函数

var count1 = [];
    for (var i = 0; i < 10; i++) {
        count1.push(function() {
            console.log(i);
        });
    }
    count1.forEach(function(count1) {
        count1();
        //输出了 10个 10
    });

       在当时学习JavaScript的时候你可能会认为结果是依次输出0-9,而事实则是输出了 10个 10,因为变量i在循环的每次迭代中都被共享,意味着循环内创建的哪些函数都拥有对于同一变量的引用。这个原因大家应该还都记着。那怎么解决呢?一般当时都是采用立即执行函数的方式。

    var count2 = [];
    for (var i = 0; i < 10; i++) {
        count2.push((function(value) {
            return function() {
                console.log(value);
            }
        }(i)));
    }
    count2.forEach(function(count2) {
        count2();
        //依次输出0 1 2 3 4 5 6 7 8 9
    })

而使用ES6新增的let 则不用这么麻烦,能够简化这个循环。

    var count3 = [];
    for (let i = 0; i < 10; i++) {
        count3.push(function() {
            console.log(i);
        });
    }
    count3.forEach(function(count3) {
        count3();
        // 0 1 2 3 4 5 6 7 8 9
    })

       在循环中let 声明 每次都创建了一个新的i变量,因此在循环内部创建的函数获得了各自的i 副本,而每个i 副本的值在每次循环迭代声明的时候被确定了。
7.var全局作用域上声明会创建一个新的全局变量,并成为 全局对象,而let 和 const 不是这样。

var a = 2;
console.log(a);  // 1
console.log(window.a); //1
let b = 2
console.log(b); //2
console.log(window.b === b); //false
const b = 2
console.log(b); //2
console.log(window.b === b); //false

结语

       在默认情况下使用let 比较好,因为不会出现重复声明。保护变量不被修改,使用const 比较好。本文主要介绍了ES6的变量声明。如有不当之处还请大家指出,希望关注更多,关注我哦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值