ES6总结(一)

在总结ES6之前,告诉大家一个好的网站,叫掘金网

1. 数据

  1. let
    a. 不能变量声明提升;
    b. 不能重复声明变量,这样可以防止污染变量。
  2. const
    a. 定义的时候要有初始化值;
    b. 初始化值不能改变(即绑定不能改变,也就是说内存地址是不能改变的)。
    下面增对与const中b这一点举一个例子:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 例子一
    const age = 10; // age是一个原始值
    age = 20; // 报错,因为常量是不能进行更改的
    // 例子二
    const person = {
    name: "daipi173",
    age: 22
    };
    person.sex = "female";
    console.log(person); // 此时是不会报错的,会打印出:{name: "daipi173", age: 22, sex: "female"}

2. 块级作用域

  1. let、const声明的变量不会被绑定给window,但是var就会,语法:{块级作用域}。
    如:
    1
    2
    3
    4
    {
    let a = 1;
    }
    console.log(a); // 报错,报错信息为:a is not defined

3. 声明变量let暂时性死区

  1. 在理解暂时性死区之前,我们需要先知道一点,先看看下面一段代码:
    1
    2
    3
    4
    5
    console.log(a)
    var a; // undefined,由于变量声明提升,因此该代码等价于下面两行的代码
    // 等价于
    // var a
    // console.log(a) // undefined
    在ES6中,使用let声明的时候,又会产生不同的结果:
    1
    2
    console.log(a); // ReferenceError: a is not defined
    let a;
    为什么会出现不同的结果,其原因就是因为我们忽略了let的暂时性死区(temporal dead zone,简称TDZ)。
  2. 为什么会出现暂时性死区
    ES6规定,let/const 命令会使区块形成封闭的作用域。若在声明之前使用变量,就会报错。
    总之,在代码块内,使用 let 命令声明变量之前,该变量都是不可用的。
    这在语法上,称为 “暂时性死区”( temporal dead zone,简称 TDZ)。
    我们来举一个例子:
    1
    2
    3
    4
    5
    var a = 123;
    if(true){
    a = 'abc'; // 报错
    let a;
    }
    在上面的代码中,存在全局变量a,但是块级作用域内let又声明了一个局部变量a,导致后者绑定了这个块级作用域,所以在let声明变量前,对a赋值会报错。

注意:ES6明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域,凡是在声明之前就使用这些变量,就会报错。

  1. 暂时性死区的其他影响
    TDZ 也意味着 typeof 不再是一个百分之百安全的操作。在没有 let 之前,typeof 运算符是百分之百安全的,不会报错。
    1
    2
    typeof a; // ReferenceError: a is not defined
    let a;

4. 字符串拓展

  1. includes方法
    includes判断一个字符串是否在一串字符串中,返回true或者false。它和indexOf相似,只不过它返回的是-1或索引值。
    如:
    1
    2
    let msg = 'hello';
    console.log(msg.includes('h',2)); // false,这里的2表示从第三位开始查找(包括第三位)
    关于该方法我们还可以做一个兼容性处理,利用String.prototype.includes,用ES5的方法(兼容性写法)来实现一下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    if(!String.prototype.includes){
    String.prototype.includes = function(search,start){
    if(typeof start !== "number"){
    start = 0;
    }
    if(start + search.length > this.length){
    return false;
    }else{
    return this.indexOf(search,start) !== -1;
    }
    };
    }
  2. startsWith方法
    startsWith判断是否是以某个字符或者字符串开头,返回true或false。
    如:
    1
    2
    3
    4
    5
    6
    let msg = 'hello';
    console.log(msg.startsWith('h')); // true
    console.log(msg.startsWith('hell')); // true
    console.log(msg.startsWith('hello')); // true
    console.log(msg.startsWith('hell',1)); // false,表示从第2位开始查找(包含第2位)
    console.log(msg.startsWith('ell',1)); // true
  3. endsWith方法
    endsWith表示判断是否是以某个字符串或某串字符串结尾的,返回true或者false。
    如:
    1
    2
    3
    let msg = 'hello';
    console.log(msg.endsWith('llo')); // true
    console.log(msg.endsWith('l',1)); // false,这里面的1表示从第1位之前开始查找(包括第1位)
  4. repeat方法
    repeat表示去重复一个字符串。
    如:
    1
    2
    let msg = 'hello';
    console.log(msg.repeat(3)); // hellohellohello,这里面的3表示重复3次

5. 解构赋值

  1. 数组解构赋值
    语法:[variable1,variable2,…,variableN] = array;
    如:
    1
    2
    3
    let arr = [1,2,3];
    let [a,b,c] = arr;
    console.log(a,b,c); // 1 2 3
    使用是需注意:
    a. 必须要进行初始化
    b. 可以在解构中忽略一些项;
    如:
    1
    2
    3
    let arr = [1,2,3];
    let [,a,] = arr;
    console.log(a); // 2
    c. 互换两个变量的值。
    如:
    1
    2
    3
    4
    let x = 1;
    let y = 2;
    [x,y] = [y,x]; // 在这里[x,y]前面不用let声明了,因为x,y是声明过了的
    console.log(x,y); // 2 1
  2. 默认值的使用
    a. 当指定位置的项不存在;
    b. 指定位置的值为undefined。
    如:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 例1
    let [x,y] = [];
    console.log(x,y); // undefined undefined
    // 例2
    let [x=10,y=20] = [];
    console.log(x,y); // 10 20
    // 例3
    let [x=10,y=20] = [1,2];
    console.log(x,y); // 1 2
    // 例4
    let [x=10,y=20] = [null];
    console.log(x,y); // null 20
  3. 对象解构赋值
    先说一个对象解构赋值的小语法:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    let name = 'dai';
    let obj = {
    // 第一个name叫属性名,它本质是一个字符串,第二个name是变量
    name: name
    };
    console.log(obj); // {name: 'dai'}
    // 如果冒号左边与右边的形式一样,但是含义不同,左边是字符串右边是变量
    // 如果冒号左边与右边的形式一样,可以等价于下面的写法
    let name = 'dai';
    let obj = {
    name // ES6为了方便书写,简写成这样(属性名和属性值的形式是一样的时候,就可以缩写)
    };
    console.log(obj); // {name: 'dai'}
    如:
    1
    2
    3
    4
    5
    let {name: name,age: age} = {name: 'daipi173',age: 10};
    console.lo(name,age); // daipi173 10
    // 对于上面形式相同,我们可以简写为如下形式
    let {name,age} = {name: 'daipi173',age: 10};
    console.lo(name,age); // daipi173 10
    我们还可以这样写:
    1
    2
    let {name: name1,age: age1} = {name: "daipi173",age: 22}; // 这里面的name1和age1是变量
    console.log(name1,age1); // daipi173 22
    在使用对象解构赋值时,需要注意:
    a. 必须要进行初始化
    b. 在赋值的时候使用解构赋值。
    如:
    1
    2
    3
    4
    5
    6
    let name1,age1;
    // 在这里需要注意:必须要使用()括号其原因是因为会将{}当成一个代码块,如果代码块
    // 后面有一个'='就会报语法错误。此时就需要添加()括号告诉js引擎我们是代码块而不是
    // 表达式,表达式是一个对象。
    ({name: name1,age: age1} = {name: 'daipi173',age: 22});
    console.log(name1,age1); // daipi173 22
    c. 解构赋值表达式的值是表达式右侧的值。
    如:
    1
    2
    3
    let name1,age1;
    console.log({name: name1,age: age1} = {name: 'daipi173',age: 22});
    // {name: 'daipi173',age: 22}
    它的作用我们可以写一段代码来解释:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function fn(value){
    // 作用:此时就可以不再这里添加上
    // let name = value.name;
    // let age = value.age;
    console.log(name,age);
    console.log(value); // 打印出来就是表达式右侧的值
    }
    let obj = {
    name: 'daipi173',
    age: 22
    };
    fn({name,age} = obj);
    // daipi173 22
    // {name: "daipi173", age: 22}
  4. 对象解构赋值的默认值
    如:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 例1
    let {name,age} = {};
    console.log(name,age); // undefined undefined
    // 例2
    let {name='daipi173',age=22} = {};
    console.log(name,age); // daipi173 22
    // 例3
    let {name='daipi173',age=22} = {name: 'dai',age: 18};
    console.log(name,age); // dai 18
    // 例4
    let {name='daipi173',age=22} = {name: null,age: 18};
    console.log(name,age); // null 18
  5. 混合解构:对象和数组组合使用

注意:匹配模式:看左边与右边能否对应上。
如:

1
2
3
let [a,b,[c,d]] = [1,2,3]; // 报错,其原因就是因为左右两边没有匹配上
// 我们可以将上面的代码改为如下所示的代码
// let [a,b,[c,d]] = [1,2,[]]; 此时就不会报错了,其原因是因为左右两边匹配上了

再给大家举一个例子:

1
2
let {age: [a,b,c]} = {age: [1,2,3]};
console.log(a,b,c); // 1 2 3