const 和 let
ES6 推荐使用 let 声明局部变量,相比之前的 var(无论声明在何处,都会被视为声明在函数的最顶部),let 具有块级作用域(即在使用 let 的那一对大括号 {}内起作用),可以避免变量提升和污染全局作用域的问题。
const 则用来声明常量,即一旦赋值就不能再改变。const 也具有块级作用域,并且必须在声明时就初始化。const 适合用来定义不会改变的值,如 PI、URL 等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 var a = 1 if (true ) { var a = 2 } console .log (a) let b = 1 if (true ) { let b = 2 } console .log (b) const PI = 3.14 PI = 3.15 const URL = 'https://www.bing.com' URL = 'https://www.google.com'
解构赋值
解构赋值是一种从数组或对象中提取数据并赋值给变量的简洁写法。它可以减少代码量,提高可读性,并且支持默认值、嵌套结构、别名等特性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 let [f, g, h] = [1 , 2 , 3 ]console .log (f) console .log (g) console .log (h) let { name, age } = { name : 'Alice' , age : 18 }console .log (name) console .log (age) let { name : i, age : j } = { name : 'Bob' , age : 19 }console .log (i) console .log (j) let [k, l = 0 ] = [1 ]console .log (k) console .log (l) let { m = 0 , n = 0 } = { m : 1 }console .log (m) console .log (n) let [o, [p, q]] = [1 , [2 , 3 ]]console .log (o) console .log (p) console .log (q) let { r : { s, t }, } = { r : { s : 4 , t : 5 } } console .log (s) console .log (t) let u = 6 let v = 7 ;[u, v] = [v, u] console .log (u) console .log (v) function foo ([x, y] ) { return x + y } console .log (foo ([8 , 9 ])) function bar ( ) { return [10 , 11 ] } let [w, z] = bar ()console .log (w) console .log (z)
箭头函数
箭头函数是一种使用 => 符号定义函数的简洁写法 。它可以省略 function 关键字、参数括号、返回值括号等,使得代码更加简洁和清晰。箭头函数还有一个重要的特性,就是它不会改变 this 的指向,即箭头函数内部的 this 始终指向定义时所在的对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 function add (x, y ) { return x + y } let add = (x, y ) => x + y let square = (x ) => x * xlet hello = ( ) => console .log ('Hello' )let max = (x, y ) => { if (x > y) { return x } else { return y } } let obj = { name : 'Alice' , sayHi : function ( ) { console .log (this .name ) setTimeout (function ( ) { console .log (this .name ) }, 1000 ) setTimeout (() => { console .log (this .name ) }, 1000 ) }, } obj.sayHi () var obj = { name : 'John' , sayHello : function ( ) { var that = this setTimeout (function ( ) { console .log ('Hello, ' + that.name ) }, 1000 ) }, } obj.sayHello ()
模板字符串
模板字符串是一种使用反引号 `` 包裹字符串,并且支持插入变量或表达式的新语法 。它可以避免使用 + 号连接字符串和变量,并且支持多行字符串和标签模板等特性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 let name = 'Bob' let age = 19 let message = `Hello ${name} , you are ${age} years old.` console .log (message)let poem = `Do not go gentle into that good night, Old age should burn and rave at close of day; Rage, rage against the dying of the light.` console .log (poem)function tag (strings, ...values ) { let result = '' for (let i = 0 ; i < strings.length ; i++) { result += strings[i] if (i < values.length ) { result += values[i].toUpperCase () } } return result } let name = 'Alice' let message = tag`Hello ${name} , how are you?` console .log (message)
默认参数、剩余参数和展开运算符
ES6 提供了一些新的语法,可以让函数的参数更加灵活和方便。默认参数可以让函数在没有传入参数或传入 undefined 时,使用预设的默认值。剩余参数可以让函数接收任意数量的参数,并将它们存储在一个数组中。展开运算符可以将一个数组或对象展开为多个元素或属性,用于函数调用、数组合并、对象复制等场景。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 function add (x = 0 , y = 0 ) { return x + y } console .log (add ()) console .log (add (1 )) console .log (add (1 , 2 )) console .log (add (1 , undefined )) function sum (...numbers ) { let result = 0 for (let number of numbers) { result += number } return result } console .log (sum ()) console .log (sum (1 )) console .log (sum (1 , 2 )) console .log (sum (1 , 2 , 3 )) let arr = [4 , 5 , 6 ]console .log (sum (...arr)) let arr1 = [1 , 2 ]let arr2 = [3 , ...arr] let obj1 = { name : 'Alice' }let obj2 = { ...obj1 }
类和继承
ES6 提供了一种新的语法,可以让 JavaScript 支持类和继承这两个面向对象编程的重要概念。类是一种定义对象属性和方法的模板,可以通过 new 关键字创建类的实例。继承是一种让子类拥有父类属性和方法的机制,可以通过 extends 和 super 关键字实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Person { constructor (name, age ) { this .name = name this .age = age } sayHi ( ) { console .log (`Hello ${this .name} , you are ${this .age} years old.` ) } } let alice = new Person ('Alice' , 18 )alice.sayHi () class Student extends Person { constructor (name, age, grade ) { super (name, age) this .grade = grade } sayHi ( ) { console .log (`Hello ${this .name} , you are ${this .age} years old and in grade ${this .grade} .` ) } study ( ) { console .log (`${this .name} is studying hard.` ) } } let bob = new Student ('Bob' , 19 , 12 )bob.sayHi () bob.study ()
Promise 和 async/await
Promise 是一种用于处理异步操作的对象,它表示一个未来可能完成或失败的事件。Promise 有三种状态:pending(等待)、fulfilled(成功)、rejected(失败)。Promise 可以通过 then 方法添加成功或失败时执行的回调函数,也可以通过 catch 方法添加失败时执行的回调函数。Promise 还可以通过 all 和 race 方法组合多个 Promise 对象。
async/await 是一种基于 Promise 的新语法,可以让异步操作更加简洁和清晰。async 是一个修饰符,用于声明一个异步函数,该函数返回一个 Promise 对象。await 是一个运算符,用于等待一个 Promise 对象的结果,只能在异步函数中使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 let promise = new Promise ((resolve, reject ) => { setTimeout (() => { let num = Math .random () if (num > 0.5 ) { resolve (num) } else { reject (num) } }, 1000 ) }) promise .then ((value ) => { console .log (`Success: ${value} ` ) return value * 2 }) .then ((value ) => { console .log (`Double: ${value} ` ) }) .catch ((reason ) => { console .log (`Fail: ${reason} ` ) }) let promise1 = Promise .resolve (1 ) let promise2 = Promise .resolve (2 )let promise3 = Promise .resolve (3 )let promise4 = Promise .all ([promise1, promise2, promise3]) promise4 .then ((values ) => { console .log (values) }) .catch ((reason ) => { console .log (reason) }) let promise5 = new Promise ((resolve, reject ) => { setTimeout (() => { resolve (5 ) }, 500 ) }) let promise6 = new Promise ((resolve, reject ) => { setTimeout (() => { reject (6 ) }, 1000 ) }) let promise7 = Promise .race ([promise5, promise6]) promise7 .then ((value ) => { console .log (value) }) .catch ((reason ) => { console .log (reason) }) async function test ( ) { try { let value = await promise console .log (`Success: ${value} ` ) } catch (error) { console .log (`Fail: ${error} ` ) } } test ()
模块化
模块化是一种将代码分割为不同的文件或模块的方法,可以提高代码的可读性、可维护性和复用性。ES6 提供了一种原生的模块化语法,可以让 JavaScript 支持导入和导出模块。导入模块使用 import 关键字,导出模块使用 export 关键字。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 export function add (x, y ) { return x + y } export function multiply (x, y ) { return x * y } import { add, multiply } from './math.js' console .log (add (1 , 2 )) console .log (multiply (2 , 3 )) import { add as plus, multiply as times } from './math.js' console .log (plus (1 , 2 )) console .log (times (2 , 3 )) export { add as plus, multiply as times } import * as math from './math.js' console .log (math.add (1 , 2 )) console .log (math.multiply (2 , 3 )) export * from './math.js' export default function subtract (x, y ) { return x - y } import subtract from './math.js' console .log (subtract (5 , 4 ))
迭代器和生成器
迭代器是一种遵循迭代协议的对象,可以按照一定的顺序访问一个集合中的元素。迭代器有一个 next 方法,每次调用返回一个包含 value 和 done 属性的对象,value 表示当前元素的值,done 表示是否还有更多元素。ES6 提供了一种新的语法 for…of 循环,可以方便地遍历迭代器。
生成器是一种特殊的函数,可以返回一个迭代器对象,并且可以在函数体内使用 yield 关键字暂停和恢复执行。生成器使用 function* 关键字声明,并且可以接收参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 let iterator = { [Symbol .iterator ]() { let i = 0 return { next ( ) { if (i < 5 ) { return { value : i++, done : false } } else { return { done : true } } }, } }, } for (let value of iterator) { console .log (value) } function * generator (n ) { for (let i = 0 ; i < n; i++) { yield i } } let iter = generator (5 )for (let value of iter) { console .log (value) }
Map 和 Set
Map 和 Set 是两种新的数据结构,可以提供更高效和灵活的存储和操作方式。Map 是一种类似于对象的集合,但是它可以使用任意类型的值作为键(而不仅仅是字符串)。Set 是一种类似于数组的集合,但是它只存储唯一的值(不会出现重复)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 let map = new Map ([ ['name' , 'Alice' ], ['age' , 18 ], ]) map.set ('gender' , 'female' ) map.set (true , 'yes' ) map.set ([1 , 2 ], 'array' ) console .log (map.get ('name' )) console .log (map.get (true )) console .log (map.get ([1 , 2 ])) console .log (map.has ('age' )) console .log (map.has ('grade' )) console .log (map.delete ('age' )) console .log (map.delete ('age' )) console .log (map.size ) map.clear () console .log (map.size ) let set = new Set ([1 , 2 , 3 , 4 , 4 ])set.add (5 ) set.add (4 ) console .log (set.has (3 )) console .log (set.has (6 )) console .log (set.delete (2 )) console .log (set.delete (2 )) console .log (set.size ) set.clear () console .log (set.size ) let map = new Map ([ ['name' , 'Alice' ], ['age' , 18 ], ]) let set = new Set ([1 , 2 , 3 ])for (let [key, value] of map) { console .log (`${key} : ${value} ` ) } for (let value of set) { console .log (value) } let mapArr = [...map]console .log (mapArr) let setArr = [...set]console .log (setArr)