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 * x;let 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 39 40 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);