ES6新语法

96 阅读4分钟

一、var 、 let 和 const

1.1 let特性

  • 不可声明前置
  • 不可重复声明
  • 块级作用域
  • 暂时性死区(TDZ):在let声明变量之前都是该变量的死区,在死区内该变量不可使用。
// 使用var
for (var i = 0; i < 5; i++) {
  setTimeout(function () {
    console.log(i);
  });
}   // => 5 5 5 5 5

// 使用let
for (let i = 0; i < 5; i++) {
  setTimeout(function () {
    console.log(i);
  });
}   // => 0 1 2 3 4

1.2 const

const声明一个只读的常量。一旦声明,常量的值就不能改变。const实际上保证的是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

我们使用const时,不能只声明而不初始化值,否则会报错:

const a;
// SyntaxError: Missing initializer in const declaration

二、解构赋值

2.1 数组解构赋值

// 1. 解构声明
const [a, b, c] = [value1, value2, value3]

// 2. 修改变量的值
[a, b, c] = [value1, value2, value3]

// 3 复杂数组 (保证两边的数组形式一致)
const [a, [b], [c, [d,e]]] = [100, [200], [300, [400, 500]]]

// 4. 声明变量的时候可以有默认值 (与函数传参类似)
const [a, b, c, d = 5] = arr 
console.log(d) // 5

2.2 对象解构赋值

// 简写形式
{name, age} = {name: '张三', age: 18} //张三 ,18

// 对象形式
const obj = {
  name: '小明',
  age: 18,
  sex: '男',
  love: {
    eat: '吃饭',
    sleep: '睡觉',
    peas: '打豆豆',
  }
}

const { name, age, sex } = obj
console.log(name, age, sex) // 小明 18 男

// 解构重名
const { name: myname } = obj
console.log(myname) // 小明

// 嵌套解构
const { love: { sleep } } = obj
console.log(sleep) // 睡觉

三、字符串扩展

两个反引号 ``
特点:
	${变量} 直接解析
	${表达式} 得到表达式的结果

四、函数扩展

4.1 参数默认值

// ES6的写法
function fn(a,b=默认值) {
    
}

// ES6之前的写法
function fn(a,b) {
    if (b === undefined) {
        b = 默认值
    }
}

4.2 箭头函数

// 以前定义函数的方式 (表达式方式)
const fn = function () {}

// 箭头函数写法
const fn = () => {}

// 箭头函数简写,如果参数只有一个,可以省略括号
const fn = name => {}

// 只有一个参数,且只有一条返回语句
const fn = num => num * num

// 如果返回的是对象
const fn = name => ({ name: name })

特点:

  • this指向与谁调用了箭头函数无关,与声明箭头函数位置有关。看声明箭头函数的地方,是不是嵌套在函数内,如果嵌套在了函数内,看外层函数的this指向;如果没有被函数嵌套,指向window。
  • 箭头函数内无法获取aruguments,可以使用rest参数。
  • 箭头函数不能作为构造函数。
  • 箭头函数不能作为生成器。

适用场景

  • 使用场景:作为回调函数;
  • 不适合的场景:给对象添加方法(this指向)、构造函数、生成器函数。

五、Class语法

5.1 定义类(构造函数)

  // 定义类
  class Person {
    // 属性,会添加到实例上
    // 把所有的属性在这里声明
    name = null;
    age = null;

    // 定义构造方法 实例化的时候自动执行
    constructor(name, age = 10) {
      this.name = name;
      this.age = age;
    }

    // 方法,添加到原型上
    say() {
      console.log('MY Name is ' + this.name);
    }
    eat() {
      console.log('My age is ' + this.age);
    }

    // 静态方法 没有添加到实例上,构造函数本身的方法
    // static getClassName() {
    //   console.log('类名是 Person 构造函数本身的方法');
    // }
  }
  //   Person.getClassName(); // 相当于 Person.getClassName = function(){}

  console.log(Person); //输出整个函数
  console.log(typeof Person); // Function
  console.log(Person.name); // Person ===> name指的是这个对象的名字

  // 不能调用
  // Person();

  // 实例化
  var p = new Person('曹操', 19);
  console.log(p); // Person {name: "曹操", age: 19}
  p.say(); // MY Name is 曹操

  var p1 = new Person('吕布', 21);
  console.log(p1); // Person {name: "吕布", age: 21}
  p1.say(); // MY Name is 吕布

  var p2 = new Person();
  console.log(p2); // Person {name: undefined, age: 10}

5.2 getter 和 setter

class Person {
    firstName = '东方';
    lastName = '不败';

    get fullName() {
      return this.firstName + '_' + this.lastName;
    }

    set fullName(val) {
      const name = val.split('_');
      this.firstName = name[0];
      this.lastName = name[1];
    }
  }

  let p = new Person();
  console.log(p); //Person {firstName: "东方", lastName: "不败"}

  console.log(p.fullName); //可读可写 东方_不败

5.3 继承

  1. 使用 extends 来继承
  2. 继承之后:子类的实例的原型指向父类的一个实例,子类自己的原型指向父类 (静态方法也可以继承)
  3. 可以在子类上添加属性和方法
  4. 在子类上重写父类的方法,子类重写的方法必须调用super()

六、模块

6.1 模块中导出数据

// 模块内部
function say() {}
function eat() {}

export {
    say,
    eat
}

6.2 导入数据

import {say, eat} from '模块文件路径';