ES6学习笔记

*node下用express框架,实现一个简单的mvc

*构建工具:gulp / babel / webpack / npm

看gulp / babel 中文文档

了解 Gulp自动化,babel编译工具,webpack编译打包(文件间的依赖),webpack-stream是让webpack支持gulp

 *创建项目:(es6基础彩票实战)

创建目录/命令行处理/创建js编译任务:

      mkdir项目名称  (创建根目录并命名)

      cd项目名称

      mkdir app (放置前端代码的)

      mkdir server(创建服务器文件夹)

      mkdir tasks(构建工具的目录)

      cd app

      mkdir css/ js / views(app前端目录中创建css、js、views文件夹)

      mkdir js/class (在js中创建class文件夹)

      文件夹内初始化文件:

      touchjs/class/test.js

      touch js/index.js

      touch views/error.ejs

      touch views/index.ejs

      (服务器代码通过node使用的模板引擎,.ejs相当于.html)

      (服务器文件需要node里面的express脚手架)

      cd server

   (使用npm安装express框架)

      express  -e .(e是使用ejs模板引擎,.是指在当前目录执行)

     npm install完成安装(cd .&& npm install)

       sudo npm install -g express

       sudo npm install -gexpress-generator

      express -e脚手架自动构建

      npm install       

      npm start(启动express服务器)

      cd tasks

      mkdir util放置常见的脚本

     touch util/args.js

------------------------------------------------------------------------------------------------

      cd ../返回项目根目录

      npm init   创建package.json安装依赖包需要有它

      touch .babelrc         设置b/./abel编译工具的配置文件

      touch gulpfile.babel.js(用ES6编写一定要加上.babel)

创建模板、服务任务脚本:

      在tasks>util>args.js(处理命令行参数的脚本)文件编写

       touch tasks/scripts.js(构建处理js的脚本,构建脚本都放在tasks目录下) 

       npm install gulp gulp-if gulp-concat webpack

       webpack-stream vinyl-named gulp-livereload gulp-plumber gulp-rename gulp-uglify

 gulp-util yargs --save-dev(package.json会有所变化)

------------------------------------------------------------------------------------------------

      接着在script。js文件写代码:

    touch tasks/pages.js(处理模板的固定脚本)

    touch tasks/css.js (处理css相关任务)

    touch tasks/server.js  (处理服务器的脚本,启动服务器,文件改变浏览器自动刷新)

创建模板、服务任务脚本:(如何将写好的代码任务自动编译到server下的public里面,供服务器进行反应)

     touch tasks/browser.js(类似服务器监听)

touch tasks/clean.js

(复制一份给服务器,当文件变化时,需要清除server旧文件)

手动安装上述引用的包:

npm install gulp-live-server del gulp-util--save-dev

touch

tasks/build.js(写一个脚本,将所有文件串起来)

touch

tasks/default.js(写一个默认脚本,如果命令行只输入gulp就指定执行build文件)

npm install babel-loader babel-core babel-preset-env webpack–save-dev

写gulpfile.babel.js文件:将tasks文件下所有文件都引进来执行

(执行gulp首先找gulpfile.babel.js这个文件)   

npm install require-dir –save-dev(对上述文件引用的包进行安装)

写.babelrc文件:

{"presets": ["es2015"]}

         npm  install babel-preset-es2015  - -save-dev

npm  install  gulp-sequence --save-dev(安装遗忘的包)

         执行gulp,确定没错后执行gulp –-watch(不加这个,所有脚本只执行一次)

         执行gulp –-watch后直至livereload。。。出现

*解决服务器问题:(见最顶部红色背景)

        http://lib.csdn.net/article/nodejs/58567?knId=802

        *解决页面无变化问题:          

index.ejs里写html代码,然后看浏览器是否有变化,如果没有变化,结束进程,npm

start重新启动,刷新页面 

*解决页面不自动刷新问题:(tasks>util>args.js文件最后一行加export  default args)

*修改serverXXX问题:

    •在server下面的app.js中加一句话(使能接受热更新的东西)

•app.use(require('connect-livereload')());  这行一定要放到下面这行代码行下面app.use(express.static(path.join(__dirname, 'public')));

    •在命令行安装上述包(ctrl+c终止服务器)

    npm install connect-livereload –-save-dev

*再执行gulp –watch        , 查看浏览器是否实现自动刷新(热更新)

*在文件里写ES6 查看能否实现转码,js脚本查看效果,千万别点刷新(?)

*安装兼容处理的库(兼容ES7):npm install babel-polyfill  --save-dev

==================================================================

以后的项目都建在app>js>class文件里,然后在index.js里引进新建的文件:

例如import './class/let';然后再执行gulp –watch

                  复习时,根据笔记和项目es6一起

==================================================================

*ES6:javascript的标准   js实现

*兼容性查看:http://kangax.github.io/es5--compat-table/es6/

*谷歌兼容包:https://github.com/paulmillr/es6-shim

*环境支持:以下代码放到head里面s

*Script标签的type属性值:module 或者 traceur,而不再是text/javascript

*Js中虚拟多线程:setTimeout

*模板

   traceur.options.experimental = true;

------------------------------------------------------------------------------------------------

•ES6中箭头函数好处:在函数内部,this所指向的是函数外部,与外层this相同,不会出现this不一致的现象。

         • let命令:用于定义变量,相当于var,但与var 的作用域不同。

*Var:{ 全局,局部(函数作用域,但if代码块中不算局部)}

                                     *Let:遇到代码块就是局部作用域,包括if,出代码块就销毁

                                     *Let不存在变量提升(实例如下

*let暂时性死区:在块级作用域内使用let,let所声明的变量就绑定在这个区域,不再受外部的影响(let命令声明量之前,都属于量的死区.typeof不完全试用,这样的设计是为了让大家养成良好的编程习惯,变量一定要在声明之后使用,否则就报错)

*let不受外界影响

var a=200;{console.log(a);let a=100;console.log(a);} //undefined  100

*let模块内部不允许重复声明let  a=1;let  a=2;报错

·块级作用域:

                            1.内层变量可能会覆盖外层变量

                            2.用来计数的循环变量泄露为全局变量

•const命令:用于定义常量(波尔、字符串、123, 数组)对象({})作用域与let相同

                     *常量定义后不能通过语句改。但对象里的属性可以更改。

                     *一定要给值,不能光声明。

                     *想改变或者添加数组的值,需要用到push。Arr.push();

                                     *对象冻结:

*彻底冻结对象(对象及其属性)的函数:

*跨模块常量引用:

const声明的常量只在当前代码块有效,如果想设置/使用跨模块的常量?

         模块:如类,一个js文件

import后的*可以改写为{ 待引入文件里的变量1,变量2 }

*全局对象属性:

var命令和function命令声明的全局变量,属于全局对象的属性;

(严格模式下)let命令、const命令、class命令声明的全局变量,不属于全局对象的属性

         解构:从数组或对象中取出来后  赋值给变量。

•变量的解构赋值(数组):

                            值不存在,解构不成功,返回undefined。

                            传统数组:var arr = [1,2,3] ;           ➔       arr[0], arr[1], arr[2]

                        传统变量:var  a = 1 , b = 2 ,c = 3 ;

                        举例:几种情况

var [ a, b, c ] = [ 1,2,3 ] ;                 //  a=1 ,  b=2 , c=3 ;

                                     var[ a, b, c ] = [ 1,,3 ] ;          //  b=undefined ;

                                     var[ a , …c ] = [ 1, 2,3];                 //  a=1 , c=[2,3] ;

                            不完全解构:等号左边的模式,只匹配一部分的等号右边的数组

                            指定默认值:

var[a,b,c =’default’,d=’default’]=[1, 2, 3]  //a=1, b=2, c=3, d=default var[p ,q=’aaa’]=[‘bbb’,undefined] ; // p=bbb ,q=aaa

                                     非遍历结构:(报错)

var [a] = 1/false/NaN/undefined/null  //没有中括号,会报错

                            let/const在解构中的作用:

                            只要某种数据结构具有Iterator接口,都可采用数组形式的解构赋值。

•变量的解构赋值(对象):        

  eg:var obj={

                     a:1,

                     b:2

}    

//===============================================//

let { a, b} = obj;                                     //a=1 , b=2;

let { a:A, b} = obj ;                  //A=1,a=undefined报错

eg

                            eg:let{ a=1,b=2} ={ a:10}           //a=10,b=2

                                let{ a:A=1, b=2} = { a:10 }             //A=10,b=2给a重命名为A

                   •访问后台json数据:

          ➔➔

                   •访问一个对象中的多个方法(访问Math对象内的很多方法):

 •变量的解构赋值(其他:字符串,函数等):

输出字符串长度:let { length }= ‘yo.’;

解构字符串成数组:let [ a, b,c] = ’ yo. ’ ;

函数传参进行解构:

     (有图片)   ➔➔    (有图片)

 •新增字符串方法:

 •新增模板字符串:(可嵌套)

         •新增数据类型Symbol:(undefined、null、Boolean、String、Number、Object)?

         •新增Proxy(语言层操作对象):

·正则扩展:

ES5:

*构造正则函数:let regex=new

RegExp(‘要匹配字符串’, ’i’ ) ;

              let regex2=new RegExp(/字符串/i) ;括号内只允许一个参数

             *测试:regex.test(‘xyz123’)          regex2.test(‘xyz123’)

             *修饰符:a) i表示不区分大小写

                             b) g表示是否全局

                               * .点可以代表任何字符

ES6:

*构造正则函数: let regex3=new

RegExp(/字符串/ig,’i’) ;括号内允许两个参数

*测试:regex3.flags;        //第二个参数的修饰符会覆盖第一个参数的修饰符

             *.flags是获取正则的修饰符

             *新增修饰符:  a)  y与g相比,都是全局匹配

不同的是:g可以接着上一次匹配,直到匹配到为止

y是紧接着上一次匹配的位置,匹配不上就over,匹配得上就输出。

 *新增sticky检测是否用了y修饰符

                 a1.strick               //false

                  a2.strick               //true

b)  u处理/ unicode /                   例:/\u{61}/u.test(‘a’);

   * .点不再代表任何字符,小于0xffff 的Unicode字符

(字符Unicode编码超过两个字节  便没法识别了,超过的可以加u修饰)

·字符串扩展:(这里需要安装并引入babel-polyfill库兼容ES7)

             *Unicode编码大于0xffff时,用{}包裹编码(如:’\u{20BB7}’)

              一个汉字占两个字节16位,超出部分也算两个字节

             *文字转成unicode编码:

                      ES5:charAt(0/1/2)        charCodeAt(0/1/2)

                      ES6:codePointAt()         codePointAt().toString(16)//转换成16进制

             *unicode码转化成文字:(区别在能否处理大于0xffff的unicode字符)

                      ES5:String.formCharCode(“0x20bb7”);

                      ES6:String.formCodePoint(“0x20bb7”);

             *遍历unicode编码的方法:

                   *判断字符串中是否包含某些字符:includes()

                   eg:var str=“string”; str.includes(‘r’)       //true

*判断字符串是否以XX为起始/结束的:startWidth()endWidth()

eg:var str=“string”;

str.startWidth(‘str’)//true

                                                str.endWidth(‘ng’)  //true

                   *重复字符串:repeat()

                   eg:let str=’abc’;str.repeat(2);          //abcabc

                   *模板字符串:用``包裹模板,用${}包裹数据

                   eg:let name=’list’;

                            let info=’helloworld’;

                            let modual=`I am${name},${info}`;

*ES7草案增加:需要安装npm install babel-polyfill  --save-dev并引入js文件内

                            ·补白[从前]padStart(‘长度’,‘补白内容’)

                            ·补白[从后]padEnd(‘长度’,‘补白内容’)常用语日期07.12

·标签模板:处理多语言转化,过滤一些前面的字符串

                            ·转义raw()

                                     eg:console.log(String.raw`Hi\n${1+2}`)  // Hi\n3

                                               console.log(`Hi\n${1+2}`)             //Hi回车3

·数值扩展:

  *输出二进制:console.log(0b111110111);              //503

  *输出八进制:console.log(0o767);                                    //503

  *判断数字是否为有穷:Number.isFinite(158/0)     //false(NaN)

  *判断是不是数组:Number.isNaN(NaN)                         //true

  *判断是不是个整数:Number.isInteger(25.0)                  //true

  *判断存储范围是否在(-2^53-2^53)之间:Number.isSafeInteger(a)  数字//false

  *判断带小数的整数部分并返回:Math.trunc(4.1)          //4

  *判断数字是正数负数或0:Math.sign(5/-5/0/’50’/’foo’)          //-1/1/0/1/NaN

  *立方根:Math.cbrt(-1/8)              //-1/2

·数组扩展:

  *把一组数据变量转化成数据类型Array.of(3,4,5,6)        //[3,4,5,6]

  *伪数组或集合转化成数组:Array.from(一个参数)

(如.querySelectorAll(‘p’);返回的是集合)

                            let  p = document.querySelectorAll(‘p’);

                            let  pArr=Array.from(p);                        //将p集合转化成数组

                            pArr.forEach(function(item){                   //遍历操作数组

                                     console.log(item.textContent);

                            })

                   *映射,类似map:Array.from(多个参数)

                            Array.from(  [1,3,5] ,  function(item){

                                     returnitem*2       //2,6,10

                            })    //把第一个参数的数组重新遍历一遍执行函数内(映射)

         *填充数组(数组内所有数据被改变):fill(‘替换内容’,起始位置,替换长度)

                            [1,’a’,undefined].fill(7)          //7,7,7

                            [‘a’,‘b’,‘c’].fill(7,1,3);  //a,7,7

         *数组的遍历:(let XX of []是遍历数组中的XX)

                    ·let…of…配合key() :返回所遍历数组的索引

                                   for(letindex of [‘1’,’c’,’ks’].keys()){

                                             console.log(index);                //  0,1,2

                                    }

·let…of…配合values() :返回所遍历数组的值

                        for(let index of [‘1’,’c’,’ks’].values()){

                                             console.log(index);                //  1,c,ks

                           }    

·let…of…配合entries()

:返回所遍历数组的索引和值

                                for(letindex of [‘1’,’c’,’ks’].entries()){

                                             console.log(index,value);                //01,1c,2ks

                                }

                            ·当前数组内部,把指定位置成员赋给其他位置上

                                     copyWidth(开始替换d位置,开始读数据d位置,中止读数据d位置)

                            [1,2,3,4,5].copyWithin(0,3,4)         // [4,2,3,4,5]

·数组中查找一个元素:(只找到一个元素后便返回) :find()

       [1,2,3,4,5,6].find(function(item){returnitem>3})       //4

·数组中查找一个元素的索引:(只找到一个元素后便返回其索引):findIndex()

       [1,2,3,4,5,6].findIndex(function(item){returnitem>3})     //3

·数组中是否包含一个元素:(只找到一个元素后便返回) :includes()

       [1,2,NaN].includes(1/NaN)     // true / true

·函数扩展:

  *函数参数默认值:

   eg:function test(x,y=’world’){console.log(x,y)}        

             test(‘hello’);                //hello,world

             test(‘hello’,’kill’);        //hello, kill

注:默认值后的参数不能再用没默认值的变量(:不能在参数y=world’后面加一个没有默认值的参数,可以加z=’haha…’)

 *函数作用域:

let x=’haha’;                         let x=’haha’;

function test(x,y=x){              function test(c,y=x){

           console.log(x,y);                    console.log(x,y);

      }                                         }

test(‘kill’)  //kill kill            test(‘kill’)  //kill haha

*把一系列调用函数时的参数转化为数组:rest参数(…):

     function test(…arg){

              for(let v oforg){

                   console.log(v);

               }

      }      test(1,2,3,4,’a’);         //1,2,3,4,a

注:rest参数后不能有别的参数了

 *扩展运算符(rest逆向:把数组拆成离散的值):

     console.log(…[1,2,4]);        //1 2 4

    console.log(‘a’,…[1,2,4]);         //a1 2 4

      *箭头函数:!

等号前是函数名,箭头前是参数(无参是用()代替),箭头后是返回值

let arrow = v=> v*2

arrow(3)          //6

 *伪调用:(提升性能,函数嵌套时使用)

     functiontail(x){console.log(x)}

     function fx(x){returntail(x)}

     fx(123)                       //123

·对象扩展:(不是类生成的,而是Object)    key必须是字符串

 *简洁表达:

         let o=1,k=2;                          let o=1,k=2;

         let es5={                              let es6={

                o:o,                                     o,

                k:k,                                     k,

                hello:function(){                    hello(){

                }                                         }

         }                                         }

 *属性表达式: 

         let a=’b’;

         let es5={                letes6={

                a:’c’,                     [a]:’c’

                b:’c’

         };                          }  //Object{b:c}

 *判断字符串是否相等:Obeject.is(‘’,’’)           相当于===

 数组是引用类型,引用地址不同,判断数组相等,返回false

 *拷贝(浅复制):Object.assign({a:’a’},{b:’b’})        //object{a:’a’,b:’b’}

 浅复制:引用类型只拷贝引用地址,不拷贝值

 这个方法只拷贝自身,不会拷贝继承、不可枚举的属性

        *拷贝(浅复制):entries()配合遍历(见数组扩展部分)

·运算符扩展:(不兼容)

let{a,b,…c}={a:’test’,b:’kill’,c:’ddd’,d:’ccc’}

                            c={

                                   c:’ddd’,

d:’ccc’

}

·Symbol数据类型:

         Symbol数据类型提供一个独一无二的值(永远不相等,独一无二)用for… in…或者let…of…都拿不到值

       用法1:

         let a1=Symbol();           //声明

  let a2=Symbol();   

 console.log(a1===a2)   //false

用法2:有key值,能够再次使用

  let a3=Symbol.for(‘a3’);

         let a4=Symbol.for(‘a3’);

  console.log(a3===a4)   //true

用途:let a1=Symbol.for(‘abc’)     //’abc’为键值对中的key

        let obj={

               [a1]:’123’,

               ‘abc’:345,

               ‘c’:456

              } console.log(obj);        //都能取到

·let…of和for…in只拿得到非Symbol变量,

·解决let…of和for…in拿不到Symbol变量问题:(只拿到Symbol变量)

       Object.getOwnPropertySymbols(obj).forEach(function(item){…..})

·以上两种都拿到:

       Reflect.ownKeys(obj).forEach(function(item){……})

·数据结构:(增删改查)

 ·Set数据结构:(用add添加)

*size表示set类型数据长度,set类似于数组,但重复的数据不算(利用set做到去重

 new Set (  )

                     eg:let arr = [1,2,3,1,2] ;

                         letlist=new Set(arr);

                         console.log(list);               //1,2,3

                        letarr1 = [1,2,3,1,’2’];

                        letlist1=new Set(arr1);

                        console.log(list1)                     //1,2,3,”2”

             *add添加    list1.add(5);                       //1,2,3,“2”,5

              *delete删除list1.delete(5);                 //1,2,3,”2”

              *clear清空   list1.clear();                       // [ ]

              *has包含     list1.has(5);                       // false

              *读取(用let of遍历,不论遍历.key()还是.values(),都返回其value本身;或用xxx.forEach()遍历)

·WeakSet数据结构:(与set支持的数据类型不同,它只支持对象,与垃圾回收不挂钩)

       *只能add对象,其他类型不支持

       *不能遍历

       *没有clear方法

       *没有set属性

·Map数据结构:(用set添加)

*map中的key可以是任何数据类型,不单单是String

1.let map = new Map();            2.letmap = new Map([[‘a’,123],[‘b’,456]]);

               let arr=[‘123’];                      

               map.set(arr);

              *size获取map的长度

              *get获取某元素eg:map.get(arr);

              *delete删除元素

              *clear清空元素

              *遍历:与set一样

·WeakMap数据结构:(与set支持的数据类型不同,它只支持对象)

*只能add对象,其他类型不支持

       *不能遍历

       *没有clear方法

       *没有set属性

·Map与Array的对比:

                                          Map                          数组

                     let map=new Map();                 let array=[];

       *增:       map.set(‘t:1’);                           array.push({t:1});

              *删:       map.delete(‘t’);                         let X=array.findIndex(item=>item.t);   array.spliice(index,1)

              *改:       map.set(‘t’,2)                            array.forEach(item=>item.t?item.t=2:’’);

              *查:       map.has(‘t’); //true或false       array.find(item=>item.t);//返回存在的值

·Set 与Array的对比:

                                   Set                                   数组

                     let set=new Set();              let array=[];

       *增:       set.add({t:1});                          array.push({t:1});

              *删:       set.forEach(item=>item.t?set.delete(item):’’);     

let X=array.findIndex(item=>item.t);   array.spliice(index,1)

              *改:       set.forEach(item=>item.t?item.t=2:’’);        

array.forEach(item=>item.t?item.t=2:’’);

              *查:       set.has(‘t:1’);//true或false       array.find(item=>item.t);//返回存在的值

·Map / Set 与Object的对比:

              letitem={t:1};    let map=new Map();        let set=new Set(); letobj={}

                            Map                            Set                              Object

              *增:  map.set(‘t’,1)        set.add(item)                obj[‘t’]=1

              *删:  map.delete(‘t’)        set.delete(item)             delete obj[‘t’]

              *改:  map.set(‘t’,2)          item.t=2直接修改数据        obj[‘t’]=2;

              *查:  map.has(‘t’)            set.has(item)                 ‘t’ in obj

*建议:优先使用map,如果对数据要求唯一性使用set,放弃使用object和Array

·ProxyReflect    (两者的方法一模一样)

* Proxy: 代理商,连接用户和最真实的对象中间的层

* Reflect: 反射,反射的是object

方法:get / set / has /

deleteProperty / ownKeys。。。。

•Proxy实例:

[if !vml]

[endif][if !vml]

不支持该协议取消重新上传

[endif]

不支持该协议取消重新上传

•Reflect实例:

[if !vml]

[endif]

不支持该协议取消重新上传

·ProxyReflect使用场景:(与业务解耦的数据校验模块)

     [if !vml]

[endif] [if !vml]

不支持该协议取消重新上传

[endif]

不支持该协议取消重新上传

         接图中实例:

              person.name=48;               //报错(正常ES5修改对象属性是不报错的)

              这是因为Person中的构造函数返回的不是this,而是this的代理

              即,validator返回的是代理  

·类与对象:

·类的创建与实例化:

         类里有构造函数,不再需要function(){this.XXX},只需要class关键字

 class Parent{

               constructor(name=’hanna’){

      this.name=name;

}

}     let parentHan=new Parent(‘hanliu’);  //Parent{name:”hanliu”}

·继承(extends)

//继承class Parent{

constructor(name='parent'){

this.name=name;

    }

}

class Child extends Parent{

}

console.log('继承',new Child());

 ·继承(修改)传递参数[继承修改父类属性]:super(需要传递父类的属性列表)

  新定义自己属性要用this关键字,this要在super后

//继承传递参数 即是修改、新建参数class Parent{

constructor(name='parent'){

this.name=name;

    }

}

class Child extends Parent{

constructor(name='child'){

super(name);

this.type='child';

    }

}     //new

的实例中所带的参数  会覆盖构造函数里的参数console.log('继承传递参数',new Child());

·类中的getter和setter :(定义的是属性!而不是方法,形式与方法类似)

// 类中的settergetter

class Parent{

constructor(name='parent'){

this.name=name;

    }

get longName(){

return 'Miss'+this.name;

    }

set longName(value){

this.name=value;

    }

}

let v=new Parent();

console.log('getter',v.longName); //Missparent

v.longName='hello';

console.log('setter',v.longName); //Misshello

静态属性和静态方法是通过类调用,而不是通过类的实例来调用

·静态方法:(static)

//静态方法class Parent{

constructor(name='parent'){

this.name=name;

    }

static talk(){

console.log('静态方法:I am taking!');

    }

}

Parent.talk();

·静态属性:(没有关键词)

//静态属性class Parent{

constructor(name='parent'){

this.name=name;

    }

static talk(){

console.log('静态方法:I am taking!');

    }

}

Parent.

type='test';

console.log('静态属性:',Parent.type);

·Promise异步编程的解决方案:

·异步:A执行完后执行B

·传统怎样实现异步:(通过回调 / 通过事件触发)

//模拟传统的ajax

let ajax=function (callback) {

console.log('执行');

setTimeout(function () {

        callback && callback.

call()

    },

1000);

};

ajax(

function () {

console.log('timeout1')

});

·Promise实现异步:

let ajax=function () {

console.log('执行2');

//返回 Promise 实例

 return new Promise(function (resolve,reject) {

// resolve 执行下一步操作

// reject中断当前操作

setTimeout(function () {

            resolve()

        },

1000);

    })

};

// ajax()执行后返回Promise实例,实例有.then的方法(表示执行下一步)

ajax().then(function () {

console.log('promise','timeout2');

},resolve(XXX),reject(XXX))

·Promise.all ( [ XX ] )  把多个Promise实例当做一个实例,all里传数组,当数组内所有Promise实例完成后,新的Promise实例才会发生变化(Promise.all整体才会触发then()方法)

Promise.all([

 loadImg(

'http://i4.buimg.com/567571/df1ef0720bea6832.png'),

 loadImg(

'http://i4.buimg.com/567751/2b07ee25b08930ba.png'),

 loadImg(

'http://i2.muimg.com/567571/5eb8190d6b2a1c9c.png')

]).

then(showImgs)

·Promise.race ( [ XX ] )

·Promise.all()与Promise.race()使用场景:

function loadImg(src) {

return new Promise((resolve,reject)=>{

let img=document.createElement('img');

img.src=src;

img.onload=function () {

            resolve(

img);

        }

img.onerror=function (err) {

            reject();

        }

    })

}

functionshowImgs(imgs) {

    imgs.

forEach(function (img) {

document.body.appendChild(img);

    })

}

//所有图片加载完后再添加到页面

Promise.

all([

 loadImg(

'http://i4.buimg.com/567571/df1ef0720bea6832.png'),

 loadImg(

'http://i4.buimg.com/567751/2b07ee25b08930ba.png'),

 loadImg(

'http://i2.muimg.com/567571/5eb8190d6b2a1c9c.png')

]).

then(showImgs)

// 只要有图片加载完就添加到页面

Promise.race([

 loadImg(

'http://i4.buimg.com/567571/df1ef0720bea6832.png'),

 loadImg(

'http://i4.buimg.com/567751/2b07ee25b08930ba.png'),

 loadImg(

'http://i2.muimg.com/567571/5eb8190d6b2a1c9c.png')

]).

then(showImgs)

·Iteratorfor…of循环(操作数据结构:数组、object、Map、Set)

·Iterator接口:读取数据集合(数组、object、Map、Set)它是Symbol的方法

                            arr[Symbol.iterator]( ) ;   //对数组使用Iterator接口

let arr=['hello','world'];

let map=arr[Symbol.iterator]();

console.log(map.next()); //{value: "hello", done: false}

console.log(map.next()); //{value: "world", done: false}

console.log(map.next()); //{value: undefined, done: true}

·for…of循环:不同的数据结构通过for…of不断调用不同的literaor接口,达到读取数据结构集合,对象不能用for…of获取,需要部署Iterator接口

·自定义Iterator接口,使得可以使用for…of循环

  Iterator方法最终要return返回一个对象,这个对象一定要有next方法

let obj={

start:[1,3,2],

end:[7,9,8],

    [Symbol.

iterator](){

let self=this;

let index=0;

let arr=self.start.concat(self.end);

let len=arr.length;

return {

next(){

if (index

return {

value:arr[index++],

done:false //表示未结束

                    }

                }

else{

return{

value:arr[index++],

done:true //表示结束

                    }

                }

            }

        }

    }

}

for (let key of obj){

console.log(key) }

·Generator函数:异步编程的一种解决方案(类似Promise,更高级)

 需要引入babel                           èèè                 !!!import 'babel-polyfill';

·generator基本定义:

let tell=function *() {

yield 'a';

yield 'b';

return 'c';           }

  对象不能用for…of获取,需要部署Iterator接口 (generator比部署接口要结简单)

let obj={};

obj[Symbol.iterator]=function* () {

yield 1;

yield 2;

yield 3;

}

for (let value of obj){

console.log('value',value);

}

·generator与Iterator接口的关系:

·generator状态积: 

let state=function* () {

while (1){

yield 'A';

yield 'B';

yield 'C';

    }

}

let status=state();

console.log(status.next()); //{value: "A", done: false}

console.log(status.next()); //{value: "B", done: false}

console.log(status.next()); //{value: "C", done: false}

console.log(status.next()); //{value: "A", done: false}

console.log(status.next()); //{value: "B", done: false}

·抽奖generator :

let draw=function (count) {

//具体抽奖逻辑

 console.info(`剩余${count}`)

}

//全局对象存储次数,太不安全,尽量避免把数据存储在全局变量中,用generator解决

let residue=function* (count) {

while(count>0){

        count--;

yield draw(count);

    }

}

let star=residue(5);

let btn=document.createElement('button');

btn.id='start';

btn.textContent='抽奖';

document.body.appendChild(btn);

document.getElementById('start').addEventListener('click',function () {

star.next();

},

false)

·长轮询generator(前端实时取得服务器端数据的变化):

//长轮询let ajax=function* () {

yield new Promise(function (resolve, reject) {

setTimeout(function () {

            resolve({

code:0})

        },

200);

    })                   }

[if !vml]

[endif]

不支持该协议取消重新上传

·Decorator :(修饰器)是函数,修改类的行为(拓展类的功能)

只在类中其作用,为类拓展功能,除babel-polyfill,还需要额外安装插件

npm install babel-plugin-transform-decorators-legacy–save-dev

同时需要修改babelrc文件: 加上"plugins": ["transform-decorators-legacy"]

//限制某个属性是只读的let readonly=function (target, name, descriptor) {

    descriptor.

writable=false;

return descriptor;

};

class Test{

@readonly //

为这个类添加行为

    time(){

return '2017-03-11'

    }

}

let test=new Test();

console.log(test.time()); //2017-03-11

test.time-function () {

console.log('reset time:');

};                               

//报错,只读属性不能修改

可以在类里面使用,也可以在类外部使用(但一定要在类的前面)

let typename=function (target,name,descriptor) {

    target.

myname='hello';

}

@typename

class Test{

}

console.log('类修饰符',Test.myname);

本例中,target指的是类本身,所以的target.属性 都是静态属性,需要用类来访问,而不是用实例来访问。

·Decorator 修饰器的第三方库:core-decorators   

 第三方库的安装:npminstall core-decorators

 安装后 直接@XXX 即可

 

 

 

 

·Decorator应用:(日志统计)

[if !vml]

[endif]

不支持该协议取消重新上传

·模块化:功能单一

模块的引入和导出:import  和  export

·文件1.js(导出) 文件2.js(导入)

//导出属性                                             //导入属性、函数以及类

export  let A=123;                                import  {A,test,Hello} from  ‘./路径’

//导出函数                                             import  {A} from  ‘./路径’

export  function test(){                       import * as  XX  from  ‘./路径’

console.log(‘test’);                          console.log(lesson.A);//从导入的所有元素

}                                                      中取出想要的元素

//导出类

export classHello{

       test(){

              console.log(‘class’);

}

}

·推荐使用方式:

//导出没有名字的对象                         //引入没有名字的对象

export default{                                       import  XX from ‘. /路径’

       A,                                                    console.log(XX.A,XX.test);

       test,

       Hello

}

注意:类中不一定要有构造函数,类中只有方法,没有属性的时候不需要构造方法

         方法声明:方法名(参数){ },且方法与方法之间没有逗号隔开

         Promise:解决回调问题,解决异步处理问题

         箭头函数的this指向: 需要在箭头函数外层,用变量保留this,是因为:箭头函数的this指向指的是定义时,而不是运行时。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 什么是ES6? ECMAScript 6.0 是继ECMAScript 5.1 之后 JavaScript 语...
    多多酱_DuoDuo_阅读 1,080评论 0 4
  • 《ECMAScript6 入门》阮一峰 读书笔记 let和constlet声明的变量仅在块级作用域内有效,var声...
    亲爱的孟良阅读 711评论 1 2
  • 箭头函数(****lambda****表达式)(agr) => { 函数体 }注:只有一个参数可以省略(),函数体...
    神刀阅读 335评论 0 0
  • 强大的for-of循环 ES6不会破坏你已经写好的JS代码。目前看来,成千上万的Web网站依赖for-in循环,其...
    Awe阅读 7,511评论 2 7
  • 终于回到家了。 再舒适的酒店都是没有温度的,济南4天,北京4天,一个多星期的旅途终于结束。 交了些朋友。无论是在信...
    文无用阅读 834评论 0 0