ES6 总结(01):变量

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

简介:

ES6:ECMAScript 6.0,在 2015 年推出,所以又叫 ES2015,以此类推:ES7 = ES2016,ES8 = ES2017…

使用ES6+ 后低版本浏览器兼容性问题解决办法:

编译的时候可以通过 babel 转换成低版本,babel 最低可以转成 ES5 版本。

一、var

ES5 以及之前的变量命名使用 var,由于当初设计的并不合理,后来 ES6 推出了 letconst 替代 var

1. var 的作用域是全局和函数作用域

作用域是指变量能够作用的范围。
全局作用域:伴随着页面的整个生命周期(window)。
函数作用域:指在函数体内定义,可在函数体内任意地方使用,出了函数范围就无法访问。

函数作用域:

var name = 'xiaoqi';
function useVar(isNew) {
    // 使用 var 在函数作用域申明变量 age
    if (isNew) {
        var age = 20;
        // age 还可以继续声明
        var age = 18;
    }
    // 可以正常访问 if {} 块级作用域中定义的 age 变量,因为是函数作用域
    console.log(age); // 18
}
useVar(true);
console.log(name); // xiaoqi
console.log(age); // 函数作用域的变量在函数外无法访问: ReferenceError: age is not defined
复制代码

全局作用域:

// var 不支持封闭作用域
for(var i = 0;i < 3; i++){
    console.log(i); // 依次 0,1,2
}
console.log(i); // 3

// 变量会提升到 window 全局上,如果不想提升到 window,可以用函数包住变成函数作用域:
(function () {
  for(var i = 0; i < 3; i++){
      console.log(i);
  }
})
// 函数作用域的变量在函数外无法访问
console.log(i); // ReferenceError: i is not defined
复制代码

2. var 变量提升

var 申明变量有很大弊端。它会使变量提升,也就是说在 js 代码执行之前,js 引擎把变量和函数的声明部分提升到对应作用域的开始位置。对于 var 声明的变量,变量提升后,它的初始值是 undefined。比如:

// call 这个函数被提升了
call();
function call() {
  // name 被提升了
  console.log(name); // undefined
  var name = 'xiaoqi';
  console.log(name); // xiaoqi
}
复制代码

二、let

1. 块级作用域

ES6 中提出了 let,使用 let 声明的变量是块级作用域,也就是说在 {} 中声明的变量只能在这个块内部使用。同一变量不可以重复申明。

// 下面3种情况都属于块级作用域
for(let i = 0; i < 2; i++) {
    // 块
}
if (true) {
    // 块
}
function call() {
    // 块
}

// 关于 let 的使用:
function callLet(isNew) {
  if (isNew) {
    let address = 'WuXi';
    // 可以再次被赋值
    address = 'SuZhou';
    // 不能再次被定义
    let address = 'NanJing'; // Uncaught SyntaxError: Identifier 'address' has already been declared
  }
  
  // address 只能在定义它的块级作用域中能够使用
  // console.log(address); // Uncaught ReferenceError: address is not defined

  // 在不同的作用域中是可以重复定义的
  let address = 'ShangHai';
  console.log(address);
}
callLet(true);
复制代码

2. 必须先声明再使用

对于 let 声明的变量,如果在未申明时使用会报错,比如下面的代码:

function call() {
    console.log(name); // Uncaught ReferenceError
    let name = 'xiaoqi';
}
call();
复制代码

3. let 的暂存死区,当前作用域绑定了变量,就不会往上层作用域查找

let a = 1;
function callLet(){
 console.log(a);
 // let a = 2;
}
callLet();
复制代码

因为两个 a 不是同一个变量, babel 编译后是这样的

var a = 1;
{
  console.log(_a);
  var _a = 2;
}
复制代码

三、const

const 是常量声明最常用的手段。constlet 类似,不同之处在于它的不可修改,使用 const 声明的变量,声明时就要设定初始值(因为此时不设值就再也没机会了)。

// const 也是块级作用域,声明了就不能修改,指的是不能修改引用地址(对象的属性值可以修改)
function callConst(isNew) {
  if (isNew) {
      // 未初始化值
      // const job; // SyntaxError: Missing initializer in const declaration
      const job = 'iOS';
      // const 变量不能修改
      // job = 'Android'; // TypeError: Assignment to constant variable.
      const info = {
        tep: '10086',
        sex: '男',
      };
      info.sex = '女';
      // 对象的属性可以修改
      console.log(info);
  }
  const job = 'Android';
  // 在不同作用域可以定义
  console.log(job);

}

callConst(true);
复制代码

总结

1. var 声明的变量的作用域是全局或者函数级别的,而 letconst 声明的变量是块级的,一个 { } 表示一个块;

2. var 声明的变量可以修改和重新声明;let 声明的变量可以修改但不可以重新声明;const 声明的变量既不能修改也不能重新声明;

3. varlet 申明的变量可以不初始化,但是 const 声明的变量必须初始化;

4. varletconst 申明的变量都会发生变量提升(先使用后定义),var 申明的变量被初始化为 undefined,而 letconst 声明的变量不会被初始化,会报错。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享