ES6/ES2015 核心内容
let, const
let
用来声明变量,const
用来声明常量。
let
会为 JavaScript 声明块级作用域,用它声明的变量,只在 let
命令所在的代码块中有效。
let name = 'lyf'
while (true) {
let name = 'yf'
console.log(name) // yf
break
}
console.log(name) // lyf
用来计数的循环变量会泄露为全局变量:
var a = []
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i)
}
}
a[6]() // 10
使用闭包或者ES6 都可以解决这个问题,
var a = []
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i)
}
}
a[6]() // 6
const
用来声明常量,一旦声明,值就不能改变。
Class 类的支持
ES6 中添加了对类的支持,引入关键字 class
,对象的创建和继承更加清晰直观,并且父类方法的调用,实例化,静态方法和构造函数都更加形象。
// 创建类
class Animal {
// 构造器
constructor (name) {
this.name = name
}
// 实例方法
getName () {
console.log('Name: ' + this.name)
}
}
// 类的继承
class Dog extends Animal {
constructor (name) {
// 直接调用父类构造器进行初始化
super(name)
}
sound () {
console.log('汪汪汪')
}
}
var animal = new Animal('动物')
animal.getName() // 动物
var dog = new Dog('狗')
dog.getName() // 狗
dog.sound() // 汪汪汪
上面定义的类中,有 constructor
方法,这就是构造方法,this
代表实例对象。
class 之间通过 extends
继承,比如上面 Dog 类继承 Animal 所有属性和方法。
super
关键字,指代父类的实例(即父类的 this 对象)。
箭头函数
基本用法
var f = v => v
等价于:
var f = function (v) {
return v;
}
如果箭头函数不需要参数或者需要多个参数,就是用一个圆括号代表参数部分:
var f = () => 5
// 等同于
var f = function () { return 5 }
var sum = (sum1, sum2) => sum1 + sum2
// 等同于
var sum = function (sum1, sum2) {
return sum1 + sum2
}
箭头函数体内的 this
对象,是定义时的所在对象,而不是使用时所在的对象。
class Dog {
constructor () {
this.sound = '汪汪汪'
}
sounding () {
setInterval(() => {
console.log(this.sound)
}, 1000)
}
}
var dog = new Dog()
dog.sounding()
字符串模板
ES6 中允许使用反引号 ` 来创建字符串,此种方法可以包含变量,用 ${var}
表示:
// 产生一个随机数
var num = Math.random()
console.log(`num is ${num}`)
解构
ES6 按照一定的模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。
以前为变量赋值:
var a = 1;
var b = 2;
var c = 3;
ES6 允许下面这样:
var [a, b, c] = [1, 2, 3]
如果解构不成功,变量的值会变成 undefined
。下面这两种情况都属于解构不成功,foo
的值都会等于 undefined
。
var [foo] = []
var [bar, foo] = [1]
默认值
解构允许指定默认值
var [foo = true] = []
foo // true
[x, y = 'b'] = ['a'] // x = 'a', y = 'b'
[x, y = 'b'] = ['a', undefined] // x = 'a', y = 'b'
对象解构
解构不仅可以用于数组,还可以用于对象
var { foo, bar } = { foo: 'aaa', bar: 'bbb' }
foo // 'aaa'
bar // 'bbb'
对象的解构赋值实际上是以下形式的简写:
var { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' }
也就是说,对象的结构赋值的内部机制是,先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
对象的解构也可以指定默认值,
var { x = 3 } = {}
x //
var {x, y = 5} = {x: 1}
x // 1
y // 5
var {x: y = 3} = {}
y // 3
var {x: y = 5} = {x: 3}
y // 3
函数参数的解构
函数的参数也可以使用解构赋值
function add([x, y]) {
return x + y
}
add([1, 2]) // 3
下面是另外一个例子:
[[1, 2], [3, 4]].map([a, b] => a + b)
Module
ES6 提供了 Module
功能,它实现非常简单。
export
命令
模块功能主要由两个命令构成:export
和 import
。export
命令用于规定模块的对外接口,import
命令用于输入其他模块提供的功能。
export
可以用来输出变量:
var name = 'lyf'
var age = 20
var sex = 'man'
export {name, age, sex}
出了输出变量,还可以输出函数或者类(class),
export function func() {
return 'fun'
}
通常情况下,export 输出的就是本来的名字,但是可以使用 as
关键字重命名。
function v1() {}
function v2() {}
export {
v1 as func1,
v1 as func2
}
import
命令
使用 export
命令定义了的对外接口,其他 JS 文件就可以通过 import
命令加载这个模块。
// main.js
import { name, age, sex } from './xx.js'
如果想为输入的变量重新取一个名字,import
命令就要使用 as
关键字,将输入的变量重命名。
import { name as unname } from './xx.js'
模块的整体加载
除了加载某个输出值,还可以使用整体加载,即用 *
指定一个对象,所有输出值都加载在这个对象上。
// person.js
export function name () {
return 'Lyf'
}
export function age () {
return 20
}
加载这个模块,
// main.js
import { name, age } from './person.js'
上面的方法是逐一加载的方法,下面是整体加载
import * as person from './person'
console.log(person.name)
console.log(person.age)
export default
命令
export default
命令,为模块指定默认输出。
// export-default.js
export default function () {
console.log('foo')
}
import
命令可以为该匿名函数指定任何名字,这时候 import
后面不使用大括号
// import-default.js
import customerName from './export-default'
customerName() // 'foo'