ES6 学习笔记(二)

ES6 学习笔记,如有错误,欢迎指正。

笔记只记录了一些个人认为需要记住的知识点。

参考:ECMAScript 6 入门


Symbol   

    ES6 中新增了一种数据类型 Symbol 。至此,JavaScript 有 7 种 数据类型:undefined, null , 布尔(boolean),字符串(string),数值(number), 对象 和 Symbol 。

      暂时没有发现用处,研究后在补上。

Set 和 Map 数据结构

        Set       

                ES6 提供了新的数据结构 Set。它类似于数组,但是 成员的值都是唯一的,没有重复的值。可以用来 去重 !!!!!!

                Set 函数可以接受一个 数组(或者具有 iterable 接口的其他数据结构)作为 参数,用来 初始化。定义的值要放在 数组 里。

ES6 学习笔记(二)_第1张图片
set

            Set 实例的属性和方法

ES6 学习笔记(二)_第2张图片
set

                add(value):添加某个值,返回 Set 结构本身,类似 数组的 push。

                delete(value):删除某个值,返回一个布尔值,表示删除是否成功。

                has(value):返回一个布尔值,表示该值是否为Set的成员。

                clear( ):清除所有成员,没有返回值。

                size属性 : 获得Set值的数量,类似 数组的 length。

            Set 遍历操作

                Set 结构的实例有 四个 遍历方法,可以用于遍历成员。

                keys():返回键名的遍历器

                values():返回键值的遍历器

                entries():返回键值对的遍历器

                forEach():使用回调函数遍历每个成员

            由于 Set 结构没有键名,只有键值(或者说 键名和键值是同一个值),所以keys方法和values方法的行为完全一致

ES6 学习笔记(二)_第3张图片
遍历

                上面代码中,entries 方法返回的遍历器,同时包括 键名 键值,所以每次输出一个数组,它的两个成员完全相等。

ES6 学习笔记(二)_第4张图片
forEach

        Map

                ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串各种类型的值(包括对象)都可以当作键

ES6 学习笔记(二)_第5张图片
Map

                Map 也可以接受一个 数组 作为参数。该数组的成员是一个个表示键值对的数组

ES6 学习笔记(二)_第6张图片
map

                遍历方法 和 set  基本一样。


Proxy

      Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。

        就像 Vue 的 生命周期 ,Proxy 就像 钩子函数,给 目标对象 加上这些 钩子函数 或者为在执行方法前预处理一些代码。

        ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。

语法

                target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为。

            可以理解为

                var  proxy  = new Proxy( { }{ } ) ;

ES6 学习笔记(二)_第7张图片
Proxy

            上面代码中,由于设置了存值函数set,任何不符合要求的 sex 属性赋值,都会抛出一个错误,这是数据验证的一种实现方法。利用set方法,还可以数据绑定,即每当对象发生变化时,会自动更新 DOM。

           get方法的两个参数分别是 目标对象所要访问的属性名(接收3个参数,另外一个是proxy 实例本身) 

           set方法用来拦截某个属性的赋值操作。四个参数分别是 目标对象、所要访问的属性名 、属性值、Proxy 实例本身,最后一个参数可选。

             Proxy 支持的拦截操作,一共13种,可以参考 阮一峰大神的 ECMAScript 6 入门,在实际运用中在进行理解。


Promise对象

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

ES6 学习笔记(二)_第8张图片
基本用法

            then 方法可以接受 两个回调函数 作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是 Promise 对象的状态变为 rejected 时调用。其中,第二个函数是可选的,不一定要提供 。

            then方法返回的是一个 新的Promise实例 (注意,不是原来那个Promise实例)。因此可以采用链式写法,即 then方法后面再调用另一个then方法!!!!!!

ES6 学习笔记(二)_第9张图片
Promise

          Promise 新建后就会立即执行 !!!!!!

            Promise 新建后立即执行,所以首先输出的是 Promise。然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出。

ES6 学习笔记(二)_第10张图片
用Promise对象实现的 Ajax 操作

            Promise. catch ( )

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

ES6 学习笔记(二)_第11张图片
Promise. catch( )

                getJSON 方法返回一个 Promise 对象,如果该对象状态变为 resolved,则会调用then方法指定的回调函数;如果 异步操作抛出错误,状态就会变为 rejected,就会调用catch方法指定的回调函数,处理这个错误。另外,then方法指定的回调函数,如果运行中 抛出错误,也会被 catch方法捕获

             建议在所有队列最后加上 .catch( ),以免漏掉错误出来造成意想不到的问题

ES6 学习笔记(二)_第12张图片
Promise. catch 方法是.then(null, rejection)的别名

            promise.all ( ) 

                用于将多个Promise 实例,包装成一个新的 Promise 实例,返回的实例就是普通的 Promise

            接收一个 数组 作为参数,当所有子 Promise 都完成,该 Promise 完成,返回值是全部值的 数组,有任何一个失败,该Promise 失败,返回值是一个失败的 子Promise 的结果。

            Promise . all( ) 最常见的就是和 .map( ) 连用。

            promise.race( )

            只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

            常用用法:把异步操作和定时器放在一起,如果定时器先触发,就认为超时,告知用户

            把回调包装成 promise最常见,有2个好处:

            1 可读性好;2 返回的结果可以加入任何 promise 队列

            Promise.resolve( )

            有时需要将 现有对象 转为 Promise 对象,Promise.resolve 方法就起到这个作用。

ES6 学习笔记(二)_第13张图片
Promise.resolve( )

                Promise.reject( )

                Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。

ES6 学习笔记(二)_第14张图片
Promise.reject()

Generator 函数

    Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。

      形式

ES6 学习笔记(二)_第15张图片
Generator 函数

                Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用 yield 表达式,定义不同的 内部状态。

                上述示例,它内部有两个yield表达式(hello 和 world),即该函数有三个状态:hello,world 和 return 语句(结束执行)。

                Generator 函数的调用方法与普通函数一样,也是在函数名后面加上一对圆括号。但是,调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,必须调用遍历器对象的 next 方法,使得指针移向下一个状态,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。

                调用 Generator 函数,返回一个遍历器对象,代表 Generator 函数的 内部指针。以后,每次调用遍历器对象的next方法,就会返回一个有着 valuedone 两个属性的对象。value 属性表示当前的内部状态的值,是 yield 表达式后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。

                遍历器对象的next方法的运行逻辑如下。

                (1)遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的 value属性值

                (2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。

                (3)如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将 return 语句后面的表达式的值,作为返回的对象的 value属性值

                (4)如果该函数没有return语句,则返回的对象的value属性值为undefined。

                注意

                (1) yield表达式只能用在 Generator 函数里面,用在其他地方都会报错。

                (2)yield 表达式如果用在另一个表达式之中,必须放在 圆括号 里面。

ES6 学习笔记(二)_第16张图片
注意

                    next 方法的参数

                    yield 表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该 参数就会被当作上一个yield表达式的返回值

ES6 学习笔记(二)_第17张图片
   next 方法的参数

                由于 nex t方法的参数表示上一个yield表达式的返回值,所以在第一次使用next方法时,传递参数是无效的。

                具体运用情形在实际运用中分析和总结。


async / await 函数 (重难点)

        async 函数是什么?一句话,它就是 Generator 函数的语法糖。

        async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句

        返回 Promise 对象

        async函数内部 return 语句返回的值,会成为 then 方法回调函数的参数

ES6 学习笔记(二)_第18张图片
return

            上面代码中,函数 f 内部return命令返回的值,会被then方法回调函数接收到。

            async函数内部抛出错误,会导致返回的 Promise 对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到。

ES6 学习笔记(二)_第19张图片
抛出错误

            Promise 对象的状态变化

                async 函数返回的 Promise 对象,必须等到内部 所有await命令 后面的 Promise 对象执行完,才会发生状态改变,除非遇到 return 语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。

            await 命令

                正常情况下,await命令后面是一个 Promise 对象。如果不是,会被转成一个立即resolve的 Promise 对象

ES6 学习笔记(二)_第20张图片
await

                    await命令后面的 Promise 对象如果变为 reject状态,则 reject的参数 会被catch方法的回调函数接收到。

ES6 学习笔记(二)_第21张图片
Promise 对象变为 reject状态

              只要一个 await 语句后面的 Promise 变为 reject,那么整个async函数都会中断执行。

ES6 学习笔记(二)_第22张图片
await

            有时,我们希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个await放在 try...catch 结构里面,这样不管这个异步操作是否成功,第二个await都会执行。

ES6 学习笔记(二)_第23张图片
错误处理

                注意

                      (1)  await 命令后面的Promise对象,运行结果可能是 rejected,所以最好把所有await命令放在try...catch代码块中

                      (2) 多个await命令后面的异步操作,如果不存在继发关系(即先后触发关系),最好让它们 同时触发,可以节约 程序的时间,提高效率。

ES6 学习笔记(二)_第24张图片
优化

                        (3)await命令只能用在 async 函数之中(跟 yield 一样),如果用在普通函数,就会报错。


Class类的使用

    JavaScript 语言中,生成实例对象的传统方法是通过构造函数。

ES6 学习笔记(二)_第25张图片
构造函数

            ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。

ES6 学习笔记(二)_第26张图片
class

                    构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。

ES6 学习笔记(二)_第27张图片
es6

        constructor 方法是类的 默认方法通过new命令生成对象实例时,自动调用该方法 !!!!!!!!

一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被 默认添加

construtor 可以用来 初始化对象

            类必须使用new调用,否则会报错。


Module 的语法

                主要用于前端,后端使用 CommonJS 。CommonJS是服务器模块的规范,Node.js采用了这个规范。

                模块功能主要由两个命令构成:export import 。export 命令用于规定模块的对外接口,import 命令用于输入其他模块提供的功能。

                export

                一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用 export关键字输出该变量

ES6 学习笔记(二)_第28张图片
export

            注意规范

ES6 学习笔记(二)_第29张图片
错误示例

            暴露方法也是一样的 export function XXX(){    }  或者 定义好方法 export { 方法名称 }

              import 

            使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过 import 命令加载这个模块。

            import命令接受 一对大括号, 里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块 对外接口的名称相同

            import {  变量名1,变量名2,变量名3.......... } from 文件路径 ;

            注意:

            ① import命令具有提升效果,会提升到整个模块的头部,首先执行。(类似于function声明)

            ② 由于 import 是 静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构。

ES6 学习笔记(二)_第30张图片
错误示例

               ③ 如果多次重复执行同一句import语句,那么只会执行一次,而不会执行多次。

                export default 命令

                    使用import命令的时候,用户需要知道所要加载的 变量名或函数名,否则无法加载。为了方便,让用户不用阅读文档就能加载模块,就要用到 export default 命令,为模块指定 默认输出 

ES6 学习笔记(二)_第31张图片
 export default

                export default 命令用于指定模块的默认输出。显然,一个模块只能有一个默认输出,因此 export default 命令只能使用一次。所以,import命令后面才不用加大括号,因为只可能唯一对应export default命令。

            本质上,export default就是输出一个叫做 default的变量或方法,然后系统允许你为它取任意名字

ES6 学习笔记(二)_第32张图片
export default

                        正是因为export default命令其实只是输出一个叫做default的变量,所以它后面不能跟变量声明语句

                        同样地,因为export default 命令的本质是将后面的值,赋给 default 变量,所以可以直接将一个值写在 export default 之后。

                        比如,export default 100;

                        export 100 是错误的!!!!!

                    export 与 import 的复合写法

ES6 学习笔记(二)_第33张图片
复合写法

                    注意

                        但需要注意的是,写成一行以后,foo和bar实际上并没有被导入当前模块,只是相当于对外转发了这两个接口导致当前模块不能直接使用foo和bar


    总结:大部分都是 文档 的 原话摘抄, 对实际理解还是不够透彻,在实际项目和实际运用场景中在加以理解。

你可能感兴趣的:(ES6 学习笔记(二))