🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# ES6 ## Default Parameters(默认参数) 在 ES5 中定义默认参数需要一下这样: ```javascript function fun(a) { var a = a || 'default value'; console.log(a); } fun('a'); //log a fun(); //log default value fun(0); //log default vaule (error) ``` 但是这样存在一个问题:如果传入的参数 a 为 0,那 fun() 方法就会出错,因为 0 代表 false。 在 ES6 中,我们可以这样定义默认参数: ```javascript function fun(a = 'default value') { console.log(a); } //不仅代码更加简洁,而且不容易出错。 fun('a'); //log a fun(); //log default value fun(0); //log 0 ``` > 定义默认参数的方式类似于 Ruby。 ## Template Literals (模板文本) 在 ES6 之前用比变量拼接字符串: ```javascript var first = 'firstName'; var last = 'lastName'; var name = 'My name is:' + first + '.' + last; ``` 在 ES6 中因为支持模板文本,所以可以写成这样: ```javascript var first = 'firstName'; var last = 'lastName'; var name = `My name is ${first}.${last}`; ``` > 注意:模板文本变量的开头和结尾不是单引号,而是反引号。 ## Multi-line Strings(多行字符串) 在 ES6 中支持反引号的多行字符串。 例如: ```javascript var str = `Hello, My name is RN.` ``` ## Destructuring Assignment(解构赋值) 我们在编码的过程中经常定义许多对象和数组,然后有组织地从中提取相关的信息片段。 在ES6中添加了可以简化这种任务的新特性:解构。 解构是一种打破数据结构,将其拆分为更小部分的过程。 下边举一个简单的例子: 在 ES5 中,我们如果想获取一个对象中的属性的值的话,一般写成这样: ```javascript var person = { name: 'MyName', age: 20, } var name = person.name; var age = person.age; console.log(name); //log MyName console.log(age); //log 20 ``` 在 ES6 中我们有更简单的写法: ```javascript var person = { name: 'MyName', age: 20, } var { name, age } = person; console.log(name); //log MyName console.log(age); //log 20 ``` > 结构赋值同样支持数组。 ## Enhanced Object Literals(增强的对象字面量) ## Arrow Functions(箭头函数) 箭头函数,属于匿名函数,使用 => 来定义函数。 下边是同一个函数,使用不同写法的对比: ```javascript var name = 'XiaoMing'; //es5 (function (name) { console.log(`Hello, everyone! My name is ${name}`) })(name) //es6 var fun = (name) => { console.log(`Hello, everyone! My name is ${name}`) } fun() //log Hello, everyone! My name is Xiaoming ``` ## Promises Promise 对象用于一个异步操作的最终完成(或失败)及其结果值的表示。简单点说,它就是用于处理异步操作的,异步处理成功了就执行成功的操作,异步处理失败了就捕获错误或者停止后续操作。 ## 状态 Promise 有三种状态,分别是 pending, fulfilled, rejected。 - pending,初始状态,也称为未定状态,就是初始化 Promise 时,调用 executor 执行器函数后的状态。 - fulfilled,完成状态,意味着异步操作成功。 - rejected,失败状态,意味着异步操作失败。 ## 状态转化 - 操作成功,pending -> dfulfilled - 操作失败,pending -> rejected ## 方法 ### then() then() 调用后返回一个 Promise 对象,意味着实例化后的 Promise 对象可以进行链式调用,而且这个 then() 方法可以接收两个函数,一个是处理成功后的函数,一个是处理错误结果的函数。 例如: ```javascript var promise = new Promise(function(resolve, reject) { // 2秒后置为接收状态 setTimeout(function() { resolve('success'); }, 2000); }); promise.then(function(data){ console.log(data) }, function(error) { console.log(error); }) ``` ### catch() catch() 方法和 then() 方法一样,都会返回一个新的 Promise 对象,它主要用于捕获异步操作时出现的异常。因此,我们通常省略 then() 方法的第二个参数,把错误处理控制权转交给其后面的 catch() 函数。 例如: ```javascript var promise = new Promise(function(resolve, reject) { setTimeOut(function() { resolve('success'); }, 2000); }); promise.then(function(data) { console.log(data); }).catch(function(error) { console.log(data); }) ``` ### Promise.all() Promise.all()接收一个参数,它必须是可以迭代的,比如数组。 它通常用来处理一些并发的异步操作,即它们的结果互不干扰,但是又需要异步执行。它最终只有两种状态:成功或者失败。 它的状态受参数内各个值的状态影响,即里面状态全部为fulfilled时,它才会变成fulfilled,否则变成rejected。 成功调用后返回一个数组,数组的值是有序的,即按照传入参数的数组的值操作后返回的结果。 ### Promise.race() Promise.race() 和 Promise.all() 类似,都接收一个可以迭代的参数,但是不同之处是 Promise.race() 的状态变化不是全部受参数内的状态影响,一旦参数内有一个值的状态发生的改变,那么该 Promise 的状态就是改变的状态。就跟 race 单词的字面意思一样,谁跑的快谁赢。 ### Promise.resolve() Promise.resolve() 接受一个参数值,可以是普通的值,具有 then() 方法的对象和 Promise 实例。正常情况下,它返回一个 Promise 对象,状态为 fulfilled。但是,当解析时发生错误时,返回的 Promise 对象将会置为 rejected 态。 ### Promise.reject() Promise.reject() 和 Promise.resolve() 正好相反,它接收一个参数值 reason,即发生异常的原因。此时返回的 Promise 对象将会置为 rejected 态。 ## Block-Scoped Constructs Let and Const(块作用域构造Let and Const) ### let let 类似 var,但是只对 {} 代码块中起作用。 ### const 声明一个只读的变量,并且需要在声明的时候赋值。 ## Classes(类) 通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法。 ES5 中定义一个类: ```javascript function Person(name,age) { this.name = name; this.age = age; ... } Person.prototype.toString = function() { return (this.name + '的年龄是' + this.age + '岁') } ``` ES6 中定义一个类: ```javascript class Person{ // 构造 constructor(x,y){ this.x = x; this.y = y; } toString(){ return (this.x + "的年龄是" +this.y+"岁"); } } ``` ## Modules(模块) - 每一个模块只加载一次, 每一个JS只执行一次, 如果下次再去加载同目录下同文件,直接从内存中读取; - 每一个模块内声明的变量都是局部变量, 不会污染全局作用域; - 模块内部的变量或者函数可以通过export导出; - 一个模块可以导入别的模块 ### export && import 模块功能主要由两个命令构成: 1. export,用于规定模块的对外接口。 2. import,用于输入其他模块提供的功能。 > 可以在 import 模块的时候使用 as 为引入的模块重新命名。 ### 说明 1. import 后面的 from 指定模块文件的位置,可以是相对路径,也可以是绝对路径,.js后缀可以省略。如果只是模块名,不带有路径,那么必须有配置文件,告诉 JavaScript 引擎该模块的位置。 2. import命令具有提升效果,会提升到整个模块的头部,首先执行。 3. 由于import是静态执行,所以不能使用表达式和变量。 4. import 除了指定加载某个输出值,还可以使用整体加载,即用星号(*)指定一个对象,所有输出值都加载在这个对象上面。 5. 13.export default命令,为模块指定默认输出,这样就可以在使用 import 命令的时候,不必知道所要加载的变量名或函数名。但是,一个模块只能有一个 export default。 6. 如果在一个模块之中,先输入后输出同一个模块,import语句可以与export语句写在一起。 例如: ```javascript export { foo, bar } from 'module'; // 等同于 import { foo, bar } from 'module'; export { foo, bar }; ``` 7. const声明的常量只在当前代码块有效。如果想设置跨模块的常量(即跨多个文件),或者说一个值要被多个模块共享,可以采用下面的写法: ```javascript // constants.js 模块 export const A = 1; export const B = 2; // test1.js 模块 import * as constants from './constants'; console.log(constants.A); // 1 console.log(constants.B); // 2 // test2.js 模块 import {A, B} from './constants'; console.log(A); // 1 console.log(B); // 2 ```