前言
这篇文章我们将会介绍 ES2015 / ES6 中一些常用的新特性
正文
1、变量定义
在 ES6 之前,定义变量只能使用 var
关键字,而在 ES6 中新增 let
和 const
关键字,它们之间的区别如下:
关键字 | 作用域 | 变量是否提升 | 能否重复定义 |
var |
函数作用域 | 是 | 能 |
let 、const |
块级作用域 | 否 | 否 |
function function_scope() { console.log(result) // undefined var result = 0 for (var count = 1; count <= 5; count++) { result += count } console.log(count) // 5 return result } function block_scope() { // console.log(result) -> ReferenceError: result is not defined let result = 0 for (let count = 1; count <= 5; count++) { result += count } // console.log(count) -> ReferenceError: count is not defined return result }
let
和 const
之间的区别如下:
- 使用
const
定义的变量在声明时必须赋值,而let
不用 - 使用
const
定义的变量声明之后不能修改,而let
不会
// const a -> Uncaught SyntaxError: Missing initializer in const declaration const a = 0 // a = 1 -> Uncaught TypeError: Assignment to constant variable.
注意哦,这里所说的不能修改,并不是说变量的值不可修改,而是变量的标识符不能重新分配
准确而言,const 声明的变量是一个值的只读引用,它意味着栈空间的地址不可修改,而非堆空间中的值不可修改
因此对于引用类型,我们还是可以修改它的值的
const a = [1, 3, 5] a[0] = 2 console.log(a) // (3) [2, 3, 5]
2、数组迭代
在 ES6 之前,使用 for 循环迭代数组有两种方式,分别是传统 for 循环和 for...in
循环
let array = ['a', 'b', 'c'] // 传统 for 循环 for (let index = 0; index < array.length; index++) { console.log(index + ': ' + array[index]) } // for...in 循环 for (let index in array) { console.log(index + ': ' + array[index]) } /* * 执行结果: * 0: a * 1: b * 2: c **/
而在 ES6 中新增 for...of
循环,可以直接遍历数组元素,而非数组索引
let array = ['a', 'b', 'c'] // for...of 循环 for (let item of array) { console.log(item) } /* * 执行结果: * a * b * c **/
在 for...of
循环中还可以使用 continue
和 break
语句
let array = [1, 2, 3, 4, 5, 6, 7, 8] let sum = 0 for (let item of array) { if (item % 2 === 0) continue sum += item } console.log(sum) // 16
3、模板字符串
模板字符串在多行字符串和字符串拼接等场景下十分方便
- ES6 之前
// 多行字符串 let html = '<ul>' + '<li>Apple</li>' + '<li>Banana</li>' + '<li>Cherry</li>' + '</ul>' console.log(html) // 字符串拼接 let protocol = 'https' let host = '127.0.0.1' let port = '80' let path = 'index.html' let url = protocol + '://' + host + ':' + port + '/' + path console.log(url) /* http://127.0.0.1:80/index.html */
- ES6 之后
// 多行字符串,保留原有格式 let html = ` <ul> <li>Apple</li> <li>Banana</li> <li>Cherry</li> </ul> ` console.log(html) // 字符串拼接,可以使用变量 let protocol = 'https' let host = '127.0.0.1' let port = '80' let path = 'index.html' let url = `${protocol}://${host}:${port}/${path}` console.log(url) /* http://127.0.0.1:80/index.html */
4、解构语法
解构语法可以将数组和对象中的值提取出来并赋值给新的变量
- ES6 之前
// 数组解构 let array = ['a', 'b', 'c'] let x = array[0] let y = array[1] let z = array[2] console.log(x, y ,z) // a b c // 对象解构 let object = { name: 'Steve', age: 18 } let name = object.name let age = object.age console.log(name, age) // Steve 18
- ES6 之后
// 数组解构 let array = ['a', 'b', 'c'] let [x, y, z] = array console.log(x, y, z) // a b c // 对象解构,变量名要与属性名相同 let object = { name: 'Steve', age: 18 } let { name, age } = object console.log(name, age) // Steve 18
解构语法还可以设置默认值和重命名变量
// 设置默认值 let array = ['a', 'b'] let [x = 'x', y = 'y', z = 'z'] = array console.log(x, y, z) // a b z // 重命名变量 let object = { name: 'Steve', age: 18 } let { name: nickName, age: nominalAge } = object console.log(nickName, nominalAge) // Steve 18
5、扩展运算符
- ES6 之前
// 数组复制 let array = ['a', 'b', 'c'] let array_copy = array.concat() console.log(array_copy) // (3) ["a", "b", "c"] // 数组合并 let array_one = ['a', 'b', 'c'] let array_two = ['d', 'e', 'f'] let array_merge = array_one.concat(array_two) console.log(array_merge) // (6) ["a", "b", "c", "d", "e", "f"] // 接收函数参数,所有传入的参数都会保存在 arguments 中 function add() { let result = 0 Array.prototype.forEach.call(arguments, function(item) { result += item }) return result } let result = add(1, 2, 3) console.log(result) // 6
- ES6 之后
// 数组复制 let array = ['a', 'b', 'c'] let array_copy = [...array] console.log(array_copy) // (3) ["a", "b", "c"] // 合并数组 let array_one = ['a', 'b', 'c'] let array_two = ['d', 'e', 'f'] let array_merge = [...array_one, ...array_two] console.log(array_merge) // (6) ["a", "b", "c", "d", "e", "f"] // 接收函数参数,剩余参数作为函数的最后一个参数,将传入的参数以数组的形式储存起来 function add(...array) { let result = 0 array.forEach(function(item) { result += item }) return result } let result = add(1, 2, 3) console.log(result) // 6
6、默认参数
在定义函数的时候,可以直接为函数参数设置默认值
- ES6 之前
function greet(somebody) { var somebody = somebody || 'stranger' console.log('Hello, ' + somebody) } greet('Amy') // Hello, Amy greet() // Hello, stranger
- ES6 之后
function greet(somebody = 'stranger') { console.log('Hello, ' + somebody) } greet('Amy') // Hello, Amy greet() // Hello, stranger
7、箭头函数
使用箭头函数不仅可以更加方便的定义函数,而且 this 的值将会继承父级执行上下文 this 的值
- ES6 之前
// 过滤奇数,元素累加 let sum = 0 let arr = [1, 2, 3, 4, 5] let even = arr.filter(function(item) { return item % 2 === 0 }) even.forEach(function(item) { sum = sum + item }) console.log(sum) // 6 // this 取值 let object = { value: 'hello', print: function() { // 使用 bind 函数将 this 的值绑定好 setTimeout(function() { console.log(this.value) }.bind(this), 1000) } } object.print() // hello
- ES6 之后
// 过滤奇数,元素累加 let sum = 0 let arr = [1, 2, 3, 4, 5] let even = arr.filter((item) => (item % 2 === 0)) even.forEach((item) => { sum = sum + item }) console.log(sum) // 6 // this 取值 let object = { value: 'hello', print: function() { // 使用箭头函数,this 的值将会继承父级执行上下文(在这里是 print 函数)this 的值 setTimeout(() => { console.log(this.value) }, 1000) } } object.print() // hello