由于在学习vue的时候有许多自己不懂的语法,于是简单的学习一下ES6。

1.ES简介

  ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本标准,2015.06 发版。

  ES6 主要是为了解决 ES5 的先天不足,比如 JavaScript 里并没有类的概念,但是目前浏览器的 JavaScript 是 ES5 版本,大多数高版本的浏览器也支持 ES6,不过只实现了 ES6 的部分特性和功能

  JavaScript 是大家所了解的语言名称,但是这个语言名称是商标( Oracle 公司注册的商标)。因此,JavaScript 的正式名称是 ECMAScript 。1996年11月,JavaScript 的创造者网景公司将 JS 提交给国际化标准组织 ECMA(European computer manufactures association,欧洲计算机制造联合会),希望这种语言能够成为国际标准,随后 ECMA 发布了规定浏览器脚本语言的标准,即 ECMAScript。这也有利于这门语言的开放和中立。

2.ES6新特性

  在这里简要的学习一下ES6的比较重要的新特性,在自己的平时工作中也没有过多的用到的ES6简要记录。

1.let与const关键字(重要)

  这两个关键字都是声明变量的关键字,其与var声明的变量有一定的区别,区别如下:

1.let解释

(1)let 声明的变量只在 let 命令所在的代码块内有效

  1. {
  2. let a = 0;
  3. var b = 1;
  4. }
  5. a // ReferenceError: a is not defined
  6. b //

(2)let 只能声明一次 var 可以声明多次:

  1. let a = 1;
  2. let a = 2;
  3. var b = 3;
  4. var b = 4;
  5. a // Identifier 'a' has already been declared
  6. b //

(3)let 不存在变量提升,var 会变量提升:

  1. console.log(a); //ReferenceError: a is not defined
  2. let a = "apple";
  3.  
  4. console.log(b); //undefined
  5. var b = "banana";

2.const关键字

  const声明一个只读变量,声明之后不允许改变。意味着,一旦声明必须初始化,否则会报错。有点类似于java的final修饰的变量,是引用不可变

  ES6 明确规定,代码块内如果存在 let 或者 const,代码块会对这些命令声明的变量从块的开始就形成一个封闭作用域。代码块内,在声明变量 PI 之前使用它会报错。

2.解构赋值

解构赋值是对赋值运算符的扩展。

他是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。

在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。

1.数组模型的解构

  1. 基本:
  2. let [a, b, c] = [1, 2, 3];
  3. // a = 1
  4. // b = 2
  5. // c = 3
  6.  
  7. 嵌套:
  8. let [a, [[b], c]] = [1, [[2], 3]];
  9. // a = 1
  10. // b = 2
  11. // c = 3
  12.  
  13. 忽略:
  14. let [a, , b] = [1, 2, 3];
  15. // a = 1
  16. // b = 3
  17.  
  18. 不完全解构:
  19. let [a = 1, b] = []; // a = 1, b = undefined
  20.  
  21. 剩余运算符:
  22. let [a, ...b] = [1, 2, 3];
  23. //a = 1
  24. //b = [2, 3]
  25.  
  26. 字符串等:
  27. let [a, b, c, d, e] = 'hello';
  28. // a = 'h'
  29. // b = 'e'
  30. // c = 'l'
  31. // d = 'l'
  32. // e = 'o'

2.对象模型的结构

  1. 基本:
  2. let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
  3. // foo = 'aaa'
  4. // bar = 'bbb'
  5.  
  6. let { baz : foo } = { baz : 'ddd' };
  7. // foo = 'ddd'
  8.  
  9. 剩余运算符:
  10. let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40};
  11. // a = 10
  12. // b = 20
  13. // rest = {c: 30, d: 40}
  14.  
  15. 解构默认值:
  16. let {a = 10, b = 5} = {a: 3};
  17. // a = 3; b = 5;
  18. let {a: aa = 10, b: bb = 5} = {a: 3};
  19. // aa = 3; bb = 5;

3.Symbol类型

ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。

ES6 数据类型除了 Number 、 String 、 Boolean 、 Objec t、 null 和 undefined ,还新增了 Symbol 。

  Symbol 函数栈不能用 new 命令,因为 Symbol 是原始数据类型,不是对象。可以接受一个字符串作为参数,为新创建的 Symbol 提供描述,用来显示在控制台或者作为字符串的时候使用,便于区分。

  1. let sy = Symbol("KK");
  2. console.log(sy); // Symbol(KK)
  3. console.log(typeof(sy)); // "symbol"
  4.  
  5. // 相同参数 Symbol() 返回的值不相等
  6. let sy1 = Symbol("kk");
  7. console.log(sy === sy1); // false

4.Map与Set

  Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。Set 对象存储的值总是唯一的。

  有点类似于Java的Map与Set。

5.Reflect 与 Proxy

  Proxy 与 Reflect 是 ES6 为了操作对象引入的 API 。

  Proxy 可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是像代理模式,通过对象的代理对象进行操作,在进行这些操作时,可以添加一些需要的额外操作。

  Reflect 可以用于获取目标对象的行为,它与 Object 类似,但是更易读,为操作对象提供了一种更优雅的方式。它的方法与 Proxy 是对应的。

  有点类似于Java的反射和代理。

6.字符串

  新增了一些方法。包括判断包含,是否以指定字符串结束、开始等操作。更加趋向于apache的StringUtils。

  也扩展了一些东西。

(1)字符的 Unicode 表示法

  ES6 加强了对 Unicode 的支持,允许采用\uxxxx形式表示一个字符,其中xxxx表示字符的 Unicode 码点。

  1. console.log("\u0061"); // a

(2).字符串的遍历器接口

  ES6 为字符串添加了遍历器接口,使得字符串可以被for...of循环遍历。

  1. for(let codePoint of 'foo') {
  2. console.log(codePoint)
  3. }
  4. // f
  5. // o
  6. // o

(3)直接输入 U+2028 和 U+2029

  1. console.log('中' === '\u4e2d') // true

(4)JSON.stringify() 的改造

  根据标准,JSON 数据必须是 UTF-8 编码。但是,现在的JSON.stringify()方法有可能返回不符合 UTF-8 标准的字符串。

(5)模板字符串

  模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。如果在模板字符串中需要使用反引号,则前面要用反斜杠转义。

例如:

  • 如果使用模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出之中。
  1. $('#app').html(`
  2. <ul>
  3. <li>first</li>
  4. <li>second</li>
  5. </ul>
  6. <p>
  7. 这里是段落
  8. </p>
  9. `);
  • 模板字符串中嵌入变量,需要将变量名写在${}之中。
  1. <div id="app">
  2. </div>
  3. <script>
  4. let user = {name: 'zs'};
  5.  
  6. $('#app').html(`
  7. <ul>
  8. <li>first</li>
  9. <li>second</li>
  10. </ul>
  11. <p>
  12. 这里是段落${user.name}
  13. </p>
  14. `);
  15. </script>

结果:

  • 大括号内部可以放入任意的 JavaScript 表达式,可以进行运算,以及引用对象属性。
  1. <script>
  2. let x = 1;
  3. let y = 2;
  4.  
  5. console.log(`${x} + ${y} = ${x + y}`)
  6. // "1 + 2 = 3"
  7.  
  8. console.log(`${x} + ${y * 2} = ${x + y * 2}`);
  9. // "1 + 4 = 5"
  10.  
  11. let obj = {
  12. x: 1,
  13. y: 2
  14. };
  15. console.log(`${obj.x + obj.y}`);
  16. // "3"
  17. </script>
  • 模板字符串之中还能调用函数。
  1. function fn() {
  2. return "Hello World";
  3. }
  4.  
  5. `foo ${fn()} bar`
  6. // foo Hello World bar
  • 如果大括号中的值不是字符串,将按照一般的规则转为字符串。比如,大括号中是一个对象,将默认调用对象的toString方法。
  • 如果模板字符串中的变量没有声明,将报错。
  • 由于模板字符串的大括号内部,就是执行 JavaScript 代码,因此如果大括号内部是一个字符串,将会原样输出。
  1. // 变量place没有声明
  2. let msg = `Hello, ${place}`;
  3. // 报错
  4.  
  5. `Hello ${'World'}`
  6. // "Hello World"
  • 模板字符串甚至还能嵌套。
  1. const tmpl = addrs => `
  2. <table>
  3. ${addrs.map(addr => `
  4. <tr><td>${addr.first}</td></tr>
  5. <tr><td>${addr.last}</td></tr>
  6. `).join('')}
  7. </table>
  8. `;
  9.  
  10. const data = [
  11. { first: '<Jane>', last: 'Bond' },
  12. { first: 'Lars', last: '<Croft>' },
  13. ];
  14.  
  15. console.log(tmpl(data));
  16. // <table>
  17. //
  18. // <tr><td><Jane></td></tr>
  19. // <tr><td>Bond</td></tr>
  20. //
  21. // <tr><td>Lars</td></tr>
  22. // <tr><td><Croft></td></tr>
  23. //
  24. // </table>
  • 如果需要引用模板字符串本身,在需要时执行,可以写成函数。
  1. let func = (name) => `Hello ${name}!`;
  2. func('Jack') // "Hello Jack!"

(6)模板编译

  通过模板字符串生成正式模板实例。

如下模板:

  1. let template = `
  2. <ul>
  3. <% for(let i=0; i < data.supplies.length; i++) { %>
  4. <li><%= data.supplies[i] %></li>
  5. <% } %>
  6. </ul>
  7. `;

  上面代码在模板字符串之中,放置了一个常规模板。该模板使用<%...%>放置 JavaScript 代码,使用<%= ... %>输出 JavaScript 表达式。

通过模板编译函数compile来生成最终的模板:

  1. function compile(template){
  2. const evalExpr = /<%=(.+?)%>/g;
  3. const expr = /<%([\s\S]+?)%>/g;
  4.  
  5. template = template
  6. .replace(evalExpr, '`); \n echo( $1 ); \n echo(`')
  7. .replace(expr, '`); \n $1 \n echo(`');
  8.  
  9. template = 'echo(`' + template + '`);';
  10.  
  11. let script =
  12. `(function parse(data){
  13. let output = "";
  14.  
  15. function echo(html){
  16. output += html;
  17. }
  18.  
  19. ${ template }
  20.  
  21. return output;
  22. })`;
  23.  
  24. return script;
  25. }

最终用法如下:

  1. let parse = eval(compile(template));
  2. $("#app").append(parse({ supplies: [ "broom", "mop", "cleaner" ] }));

结果:

(7)标签模板

  模板字符串的功能,不仅仅是上面这些。它可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为“标签模板”功能(tagged template)。

  1. alert `123`
  2. // 等同于
  3. alert(123)

  标签模板其实不是模板,而是函数调用的一种特殊形式。“标签”指的就是函数,紧跟在后面的模板字符串就是它的参数。

  但是,如果模板字符里面有变量,就不是简单的调用了,而是会将模板字符串先处理成多个参数,再调用函数。

7.ES6 数值

  对数字进行了扩展,包括Number类。

8.对象(重要)

(1)属性的简洁表示法

  1. const age = 12;
  2. const name = "Amy";
  3. const person = {age, name};
  4. person //{age: 12, name: "Amy"}
  5. //等同于
  6. const person = {age: age, name: name}

(2)方法名也可以简写

  1. const person = {
  2. sayHi(){
  3. console.log("Hi");
  4. }
  5. }
  6. person.sayHi(); //"Hi"
  7. //等同于
  8. const person = {
  9. sayHi:function(){
  10. console.log("Hi");
  11. }
  12. }
  13. person.sayHi();//"Hi"

9.数组

  增加了一些创建数组的发那个发以及数组转换的方法,也增加了数组遍历的方法。

10.函数(重要)

  这里有两个重要的改变。一个是函数的参数支持默认值以及不定参数,一个是箭头函数。

(1)参数默认值和不定参数

  1. 默认参数:
  2. function fn(name,age=17){
  3. console.log(name+","+age);
  4. }
  5. fn("Amy",18); // Amy,18
  6. fn("Amy",""); // Amy,
  7. fn("Amy"); // Amy,17
  8.  
  9. 不定参数:
  10. function f(...values){
  11. console.log(values.length);
  12. }
  13. f(1,2); //
  14. f(1,2,3,4); //

(2)箭头函数

基本语法:

  1. 参数 => 函数体

注意:

当箭头函数没有参数或者有多个参数,要用 () 括起来。

  1. var f = (a,b) => a+b;
  2. f(6,2); //

当箭头函数函数体有多行语句,用 {} 包裹起来,表示代码块,当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回。

  1. var f = (a,b) => {
  2. let result = a+b;
  3. return result;
  4. }
  5. f(6,2); //

当箭头函数要返回对象的时候,为了区分于代码块,要用 () 将对象包裹起来

  1. // 报错
  2. var f = (id,name) => {id: id, name: name};
  3. f(6,2); // SyntaxError: Unexpected token :
  4.  
  5. // 不报错
  6. var f = (id,name) => ({id: id, name: name});
  7. f(6,2); // {id: 6, name: 2}

注意:

(1)箭头函数没有 this、super、arguments 和 new.target 绑定。

  1. var func = () => {
  2. // 箭头函数里面没有 this 对象,
  3. // 此时的 this 是外层的 this 对象,即 Window
  4. console.log(this)
  5. }
  6. func(55) // Window
  7.  
  8. var func = () => {
  9. console.log(arguments)
  10. }
  11. func(55); // ReferenceError: arguments is not defined

(2)回调函数中的箭头函数的this指向外层的实例对象

  1. function fn(){
  2. setTimeout(()=>{
  3. // 定义时,this 绑定的是 fn 中的 this 对象
  4. console.log(this.a);
  5. },0)
  6. }
  7. var a = 20;
  8. // fn 的 this 对象为 {a: 19}
  9. fn.call({a: 18}); //

  call函数第一个参数相当于传递的上下文。

11.迭代器-Iterator

迭代器是一个统一的接口,它的作用是使各种数据结构可被便捷的访问,它是通过一个键为Symbol.iterator 的方法来实现。

迭代器是用于遍历数据结构元素的指针(如数据库中的游标)。

基本用法:

  通过 Symbol.iterator 创建一个迭代器,指向当前数据结构的起始位置。随后通过 next 方法进行向下迭代指向下一个位置, next 方法会返回当前位置的对象,对象包含了 value 和 done 两个属性, value 是当前属性的值, done 用于判断是否遍历结束,当 done 为 true 时则遍历结束

  1. const items = ["zero", "one", "two"];
  2. const it = items[Symbol.iterator]();
  3.  
  4. it.next();
  5. >{value: "zero", done: false}
  6. it.next();
  7. >{value: "one", done: false}
  8. it.next();
  9. >{value: "two", done: false}
  10. it.next();
  11. >{value: undefined, done: true}

for...of 循环(参见下文的 for...of 循环)对数据结构进行迭代:

  1. for (let item of ["zero", "one", "two"]) {
  2. console.log(item);
  3. }
  4. // output:
  5. // zero
  6. // one
  7. // two

12.Class 类

  在ES6中,class (类)作为对象的模板被引入,可以通过 class 关键字定义类。class 的本质是 function。它可以看作一个语法糖,让对象原型的写法更加清晰、更像面向对象编程的语法。

13.模块(重要)

  ES6 引入了模块化,其设计思想是在编译时就能确定模块的依赖关系,以及输入和输出的变量。

  ES6 的模块化分为导出(export) @与导入(import)两个模块。

特点:

ES6 的模块自动开启严格模式,不管你有没有在模块头部加上 use strict;。

模块中可以导入和导出各种类型的变量,如函数,对象,字符串,数字,布尔值,类等。

每个模块都有自己的上下文,每一个模块内声明的变量都是局部变量,不会污染全局作用域。

每一个模块只加载一次(是单例的), 若再去加载同目录下同文件,直接从内存中读取。

建议使用大括号指定所要输出的一组变量写在文档尾部,明确导出的接口。

函数与类都需要有对应的名称,导出文档尾部也避免了无对应名称。

1. 基本用法:

index.html (注意script的type设为module)

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset="utf-8" />
  6. <title></title>
  7. <script src="js/test2.js" type="module" charset="utf-8"></script>
  8. </head>
  9.  
  10. <body>
  11. <div id="app">
  12. </div>
  13. <script type="text/javascript">
  14. </script>
  15. </body>
  16.  
  17. </html>

test2.js

  1. import { myName, myAge, myfn } from "./test.js";
  2. console.log(myfn());// My name is Tom! I'm 20 years old.
  3. console.log(myAge);//
  4. console.log(myName);// Tom

test.js

  1. let myName = "Tom";
  2. let myAge = 20;
  3. let myfn = function(){
  4. return "My name is" + myName + "! I'm '" + myAge + "years old."
  5. }
  6.  
  7. export { myName, myAge, myfn }

2.as 的用法-起别名

export 命令导出的接口名称,须和模块内部的变量有一一对应关系。

导入的变量名,须和导出的接口名称相同,即顺序可以不一致。

  1. /*-----export [test.js]-----*/
  2. let myName = "Tom";
  3. export { myName as exportName }
  4.  
  5. /*-----import [xxx.js]-----*/
  6. import { exportName } from "./test.js";
  7. console.log(exportName);// Tom
  8. 使用 as 重新定义导出的接口名称,隐藏模块内部的变量
  9. /*-----export [test1.js]-----*/
  10. let myName = "Tom";
  11. export { myName }
  12. /*-----export [test2.js]-----*/
  13. let myName = "Jerry";
  14. export { myName }
  15. /*-----import [xxx.js]-----*/
  16. import { myName as name1 } from "./test1.js";
  17. import { myName as name2 } from "./test2.js";
  18. console.log(name1);// Tom
  19. console.log(name2);// Jerry

3.import 命令的特点

只读属性:不允许在加载模块的脚本里面,改写接口的引用指向,即可以改写 import 变量类型为对象的属性值,不能改写 import 变量类型为基本类型的值。

单例模式:多次重复执行同一句 import 语句,那么只会执行一次,而不会执行多次。import 同一模块,声明不同接口引用,会声明对应变量,但只执行一次 import 。

静态执行特性:import 是静态执行,所以不能使用表达式和变量。

4.export default 命令

  在一个文件或模块中,export、import 可以有多个,export default 仅有一个。

  export default 中的 default 是对应的导出接口变量。

  通过 export 方式导出,在导入时要加{ },export default 则不需要。

  export default 向外暴露的成员,可以使用任意变量来接收。

  1. var a = "My name is Tom!";
  2. export default a; // 仅有一个
  3. export default var c = "error";
  4. // error,default 已经是对应的导出变量,不能跟着变量声明语句
  5.  
  6. import b from "./xxx.js"; // 不需要加{}, 使用任意变量接收

5.复合使用

export 与 import 可以在同一模块使用,使用特点:

  可以将导出接口改名,包括 default。

  复合使用 export 与 import ,也可以导出全部,当前模块导出的接口会覆盖继承导出的

  1. export { foo, bar } from "methods";
  2.  
  3. // 约等于下面两段语句,不过上面导入导出方式该模块没有导入 foo 与 bar
  4. import { foo, bar } from "methods";
  5. export { foo, bar };
  6.  
  7. /* ------- 特点 1 --------*/
  8. // 普通改名
  9. export { foo as bar } from "methods";
  10. // 将 foo 转导成 default
  11. export { foo as default } from "methods";
  12. // 将 default 转导成 foo
  13. export { default as foo } from "methods";
  14.  
  15. /* ------- 特点 2 --------*/
  16. export * from "methods";

14.Promise 对象

  是异步编程的一种解决方案。

从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。

Promise对象有以下特点:

(1)Promise 异步操作有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。除了异步操作的结果,任何其他操作都无法改变这个状态。

(2)Promise 对象只有:从 pending 变为 fulfilled 和从 pending 变为 rejected 的状态改变。只要处于 fulfilled 和 rejected ,状态就不会再变了即 resolved(已定型)。

1.then方法:

(1)接收两个函数作为参数,第一个参数是 Promise 执行成功时(fulfilled 状态)的回调,第二个参数是 Promise 执行失败时(rejected 状态)的回调,两个函数只会有一个被调用。

  1. var myFirstPromise = new Promise(function(resolve, reject) {
  2. //当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...)
  3. //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法.
  4. setTimeout(function() {
  5. resolve("成功!"); //代码正常执行!
  6. // reject("失败"); // 异常执行
  7. }, 250);
  8. });
  9.  
  10. myFirstPromise.then(function(successMessage) {
  11. document.write(successMessage);
  12. }, function(errorMsg) {
  13. document.write(errorMsg);
  14. });

结果:

成功!

  1. var myFirstPromise = new Promise(function(resolve, reject) {
  2. //当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...)
  3. //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法.
  4. setTimeout(function() {
  5. // resolve("成功!"); //代码正常执行!
  6. reject("失败"); // 异常执行
  7. }, 250);
  8. });
  9.  
  10. myFirstPromise.then(function(successMessage) {
  11. document.write(successMessage);
  12. }, function(errorMsg) {
  13. document.write(errorMsg);
  14. });

结果:

失败

(2)可以添加多个回调函数,它们会按照插入顺序并且独立运行。then 方法将返回一个 resolved 或 rejected 状态的 Promise 对象用于链式调用,且 Promise 对象的值就是这个返回值

  1. var myFirstPromise = new Promise(function(resolve, reject) {
  2. //当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...)
  3. //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法.
  4. setTimeout(function() {
  5. resolve(1); //代码正常执行!
  6. }, 250);
  7. });
  8.  
  9. myFirstPromise.then(function(successMessage) {
  10. document.write(successMessage);
  11. return(successMessage + 1);
  12. }).then(function(successMessage) {
  13. document.write(successMessage);
  14. return(successMessage + 1);
  15. }).then(function(successMessage) {
  16. document.write(successMessage);
  17. return(successMessage + 1);
  18. });

结果:

123

2.Promise.resolve 方法:如果 Promise.resolve 方法的参数,不是具有 then 方法的对象(又称 thenable 对象),则返回一个新的 Promise 对象,且它的状态为fulfilled。

Promise.reject 方法 :也会返回一个新的Promise实例,该实例的状态为rejected。Promise.reject方法的参数reason,会被传递给实例的回调函数。

  1. var myFirstPromise = new Promise(function(resolve, reject) {
  2. //当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...)
  3. //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法.
  4. setTimeout(function() {
  5. resolve("成功1"); //代码正常执行!
  6. }, 250);
  7. });
  8.  
  9. myFirstPromise.then(function(successMessage) {
  10. document.write(successMessage);
  11. return Promise.resolve(" 成功2 ");
  12. }).then(function(successMessage) {
  13. document.write(successMessage);
  14. });

结果:

成功1 成功2

  1. var myFirstPromise = new Promise(function(resolve, reject) {
  2. //当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...)
  3. //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法.
  4. setTimeout(function() {
  5. reject("失败1"); //代码正常执行!
  6. }, 250);
  7. });
  8.  
  9. myFirstPromise.then(null, function(errorMsg) {
  10. document.write(errorMsg);
  11. return Promise.reject(" 失败2 ");
  12. }).then(function(successMessage) {
  13. document.write(successMessage);
  14. });

结果:

失败1

3.Promise.prototype.catch方法:捕捉错误

Promise.prototype.catch 方法是 Promise.prototype.then(null, rejection) 的别名,用于指定发生错误时的回调函数。

  1. getJSON("/posts.json").then(function(posts) {
  2. // some code
  3. }).catch(function(error) {
  4. // 处理前一个回调函数运行时发生的错误
  5. console.log('发生错误!', error);
  6. });

  Promise 对象的错误具有"冒泡"性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个 catch 语句捕获。

例如:一个用 Promise 对象实现的 Ajax 操作的例子

  1. function ajax(URL) {
  2. return new Promise(function (resolve, reject) {
  3. var req = new XMLHttpRequest();
  4. req.open('GET', URL, true);
  5. req.onload = function () {
  6. if (req.status === 200) {
  7. resolve(req.responseText);
  8. } else {
  9. reject(new Error(req.statusText));
  10. }
  11. };
  12. req.onerror = function () {
  13. reject(new Error(req.statusText));
  14. };
  15. req.send();
  16. });
  17. }
  18. var URL = "/try/ajax/testpromise.php";
  19. ajax(URL).then(function onFulfilled(value){
  20. document.write('内容是:' + value);
  21. }).catch(function onRejected(error){
  22. document.write('错误:' + error);
  23. });

15.Generator 函数

  ES6 新引入了 Generator 函数,可以通过 yield 关键字,把函数的执行流挂起,为改变执行流程提供了可能,从而为异步编程提供解决方案。

16. async 函数

  async 是 ES7 才有的与异步操作有关的关键字,和 Promise , Generator 有很大关联的。

语法:

  1. async function name([param[, param[, ... param]]]) { statements }
  • name: 函数名称。
  • param: 要传递给函数的参数的名称。
  • statements: 函数体语句。

返回值:

  async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。

  1. async function helloAsync() {
  2. return "helloAsync";
  3. }
  4.  
  5. console.log(helloAsync()) // Promise {<resolved>: "helloAsync"}
  6.  
  7. helloAsync().then(v => {
  8. console.log(v); // helloAsync
  9. })

结果:

async 函数中可能会有 await 表达式,async 函数执行时,如果遇到 await 就会先暂停执行 ,等到触发的异步操作完成后,恢复 async 函数的执行并返回解析值。

await 关键字仅在 async function 中有效。如果在 async function 函数体外使用 await ,你只会得到一个语法错误。

await

await 操作符用于等待一个 Promise 对象, 它只能在异步函数 async function 内部使用。

语法:

  1. [return_value] = await expression;

expression: 一个 Promise 对象或者任何要等待的值。

返回值:

返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。

如果一个 Promise 被传递给一个 await 操作符,await 将等待 Promise 正常处理完成并返回其处理结果。

await 命令后面是一个 Promise 对象,它也可以跟其他值,如字符串,布尔值,数值以及普通函数。await针对所跟不同表达式的处理方式:

  • Promise 对象:await 会暂停执行,等待 Promise 对象 resolve,然后恢复 async 函数的执行并返回解析值。
  • 非 Promise 对象:直接返回对应的值。
  1. function testAwait() {
  2. return new Promise((resolve) => {
  3. setTimeout(function() {
  4. console.log("testAwait");
  5. resolve();
  6. }, 1000);
  7. });
  8. }
  9.  
  10. async function helloAsync() {
  11. await testAwait();
  12. console.log("helloAsync");
  13. }
  14. helloAsync();

结果:

testAwait
helloAsync

ECMAScript 6.0 简要学习的更多相关文章

  1. ECMAScript 6.0 学习笔记

    1.ECMAScript 6.0(也就是ES2015 以下简称 ES6)是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了.它的目标,是使得 JavaScript 语言可以用来 ...

  2. JavaScript权威设计--JavaScript函数(简要学习笔记十一)

    1.函数调用的四种方式 第三种:构造函数调用 如果构造函数调用在圆括号内包含一组实参列表,先计算这些实参表达式,然后传入函数内.这和函数调用和方法调用是一致的.但如果构造函数没有形参,JavaScri ...

  3. 前端NEXT实践系列:(一)ECMAScript 6.0技术栈

    随着ECMAScript 6.0(ES6)是JavaScript 语言的下一代标准的普及,各个大公司和大的厂商都推出了自己的前端开发框架,如Angular,React,Vue 等,微软更是锦上添花,开 ...

  4. JavaScript权威设计--JavaScript函数(简要学习笔记十)

    1.函数命名规范 函数命名通常以动词为前缀的词组.通常第一个字符小写.当包含多个单词时,一种约定是将单词以下划线分割,就像"like_Zqz()". 还有一种就是"lik ...

  5. IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习保护API

    IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习之保护API. 使用IdentityServer4 来实现使用客户端凭据保护ASP.N ...

  6. 20145208 《Java程序设计》第0周学习总结

    20145208 <Java程序设计>第0周学习总结 阅读心得 读了老师推荐的几个文章,虽然第四个文章"为什么一定要自学"报告资源不存在而无法阅读,其他的三篇文章都言之 ...

  7. Json.Net6.0入门学习试水篇

    原文:Json.Net6.0入门学习试水篇 前言 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.简单地说,JSON 可以将 JavaScript 对象中 ...

  8. Bootstrap3.0入门学习系列

    Bootstrap3.0入门学习系列规划[持续更新]   前言 首先在此多谢博友们在前几篇博文当中给与的支持和鼓励,以及在回复中提出的问题.意见和看法. 在此先声明一下,之前在下小菜所有的随笔文章中, ...

  9. ECMAScript 6.0 简介

    ECMAScript 6.0 在es6中有 许多语法.还有lambda的使用.以及 class 的使用 还有一些新的对象来解决一些事情 可以提高开发效率 但更重要的是 颠覆 javascript 在你 ...

随机推荐

  1. 【LOJ#2687】Vim(动态规划)

    [LOJ#2687]Vim(动态规划) 题面 LOJ 题解 发现移动的路径一定是每次往后跳到下一个某个字符的位置,然后往回走若干步,删掉路径上的所有\(e\),然后继续执行这个操作. 这里稍微介绍一下 ...

  2. MVC教程:MVC区域路由

    一.区域路由 为了管理网站中大量的文件,在ASP.NET MVC 2.0版本中引入了一个新概念:区域(Area). 有了区域以后,可以让我们的项目不至于太复杂而导致管理混乱.每个模块的页面都放入相应的 ...

  3. ASP.NET MVC AJAX 请求中加入 antiforgerytoken 解决“所需的防伪表单字段“__RequestVerificationToken”不存在”问题

    在ASP.NET mvc中如果在表中使用了@Html.AntiForgeryToken(),ajax post不会请求成功 解决方法是在ajax中加入__RequestVerificationToke ...

  4. github pages与travis ci运作原理

    当说到自动部署的时候,我很反感那些一上来就balabala说怎么操作的博文文章,照着别人的做法有样学样,经常会因为与自己项目实际情况不符而出现各种问题. 比如说github和travis,首先应该搞明 ...

  5. Redis缓存系列

    一.缓存雪崩 缓存雪崩我们可以简单的理解为:由于原有缓存失效,新缓存未到期间(例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期),所有原本应该访问缓存的请求都去查询数据库了, ...

  6. call , apply的this指向实现原理并自己实现封装

    实现this指向原理 var value = 'value' var obj = { value: 'obj' } function func() { console.log(this.value) ...

  7. Android开发当中的JavaBean实现

    一般我们在Android开发当中如果会对一些数据类进行解析,那么则需要写出一个JavaBean的类,比如在进行json解析的时候,就需要使用这个类进行数据的处理,下面是我们的JavaBean的模板代码 ...

  8. MongoDB安装调试

    1:安装 去mongodb的官网http://www.mongodb.org/downloads下载32bit的包 解压后会出现以下文件 在安装的盘C:下建立mongodb文件夹,拷贝bin文件夹到该 ...

  9. Windows 10 路由表管理

    基本管理命令: route print route命令基本格式: ROUTE [-f] [-p] [-|-] command [destination] [MASK netmask] [gateway ...

  10. python的pip安装时,使用国内Pypi源

    有时,国外的网速确实不理想. 想安装python库,还是国内快点. 参考URL: http://www.mamicode.com/info-detail-2248964.html 阿里云 http:/ ...