16进制 es6_Es6语法

本文详细介绍了ES6中的新特性,包括let和const的块级作用域、解构赋值的多种方式、正则扩展的u、y、s修饰符、字符串扩展中的Unicode处理,以及数值扩展、数组扩展、函数扩展和对象扩展的相关知识点。此外,还探讨了Promise、Iterator、Generator、模块化和装饰器等核心概念及其应用场景。
摘要由CSDN通过智能技术生成

一、let和const

es6之前有两个作用域:全局作用域、函数作用域

es6新增加了块作用域,也就是{}包起来的代码

function test() {

for (let i=1;i<3;i++){

console.log(i);

}

console.log(i);//error: i is not defined

}

为什么报错?因为es6强制开启了严格模式,变量未声明不能引用

let a=3;

let a=4;

报错,不能重复声明!

const PI=3.14;

定义常量,常量不能修改!也是有块作用域的!并且,声明的时候必须赋值!

const PI=3.14,

k={

a:1

};

k.b=3;

console.log(PI,k);

可以输出。是因为k是对象,是引用类型,返回的是对象存储内存的指针,发生了修改也可以输出。

const和let的唯一区别就是,const不可以被更改,所以当声明变量的时候,尤其是在声明容易被更改的全局变量的时候,尽量使用const。

更好的代码语义化,一眼看到就是常量。

另一个原因是因为JavaScript 编译器对const的优化要比let好,多使用const,有利于提高程序的运行效率。

所有的函数都应该设置为常量。

二、解构赋值

解构赋值的分类:数组结构赋值(左右都是数组)、对象结构赋值(左右都是对象)、字符串结构赋值(左数组、右字符串)、布尔值结构赋值、函数参数解构赋值(数组解构赋值在函数上的引用)、数值解构赋值

{

let a,b,rest;

[a, b]=[1,2];

console.log(a);//1

console.log(b);//2

}

{

let a,b,rest;

[a, b, ...rest]=[1,2,3,4,5,6];

console.log(a, b, rest);//1 2 [3,4,5,6]

}

{

let a,b;

({a, b}={a:1,b:2});

console.log(a, b);//1,2

}

{

let a,b,c,rest;

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

console.log(a, b, c);//1 2 3

}

如果c没有赋值,找不到可以配对的值,c就是undifined。

适用场景:变量交换,选择性获取返回值

{

let a=1;

let b=2;

[a, b]=[b,a];

console.log(a, b);//2 1

}

{

function f() {

return [1,2];

}

let a,b;

[a, b]=f();//1 2

}

{

function f1() {

return [1,2,3,4,5];

}

let a,b,c;

[a, , ,b]=f1();

console.log(a, b);//1 4

}

{

function f1() {

return [1,2,3,4,5];

}

let a,b,c;

[a,...b]=f1();

console.log(a, b);//1 [2,3,4,5]

}

上面这两种也可以混合使用。

在用到数组成员对变量赋值时,尽量使用解构赋值。

对象的解构赋值::

{

let o={p:42,q:true};

let {p,q}=o;

console.log(p, q);//42 true

}

{

let {a=10,b=5}={a:3};

console.log(a, b);//3 5 a=10是默认值,找不到匹配项时才=10

}

使用场景:

{

let metaData={

title: 'abc',

test: [{

title: 'test',

desc: 'description'

}]

};

let {title:esTitle,test:[{title:cnTitle}]} = metaData;

console.log(esTitle,cnTitle);//abc test

}

函数的参数如果是对象的成员,优先使用解构赋值。

如果函数返回多个值,优先使用对象的解构赋值,而不是数组的解构赋值。这样便于以后添加返回值,以及更改返回值的顺序。

三、正则扩展

正则新增特性:u修饰符、y修饰符、s修饰符

{

//es5

let regex=new RegExp('xyz','i');

let regex2=new RegExp(/xyz/i);//或者直接/xyz/i

console.log(regex.test('xyz123'));//true

console.log(regex2.test('xyz123'));//true

//es6,参数可以下面这样

let regex3=new RegExp(/xyz/ig,'i');

console.log(regex3.flags);//i 即第二个参数的修饰符会覆盖前面正则表达式的修饰符

}

{

//y修饰符 vs g修饰符

let s='bbb_bb_b';

let a1=/b+/g;

let a2=/b+/y;

console.log('one',a1.exec(s),a2.exec(s));//bbb bbb

console.log('two',a1.exec(s),a2.exec(s));//bb null

相同点:都是全局匹配

不同点:g是上一次匹配的下一个字符开始,即_,不强调在第一个字符就能匹配上

不同点:y是上一次匹配的下一个字符开始,即_,但是必须得在第一个字符就能匹配上

console.log(a1.sticky,a2.sticky);//false true 是否开启y

}

{

//u修饰符:unicode

console.log('u-1',/^\uDB3D/.test('\uDB3D\uDC2A'));//u-1 true //\uDB3D\uDC2A当成两个字符

console.log('u-2',/^\uDB3D/u.test('\uDB3D\uDC2A'));//u-2 false //\uDB3D\uDC2A当成一个字符

console.log(/\u{61}/.test('a'));//false

console.log(/\u{61}/u.test('a'));//true

console.log(`\u{20BB7}`);//unicode编码大于FFFF,即大于两个字节

let s='𠮷';

console.log(/^.$/.test(s));//false

console.log(/^.$/u.test(s));//true

console.log('test',/𠮷{2}/.test('𠮷𠮷'));//test false

console.log('test2',/𠮷{2}/u.test('𠮷𠮷'));//test2 true

//总结,大于两个字节长度的字符,要加u

//但是仍然不能匹配换行符,回车符,行分隔符,段分隔符

//如果要能匹配,使用s修饰符,但是s修饰符es6尚未实现

}

四、字符串扩展

安装补丁库,处理兼容:npm install babel-polyfill --save-dev

需要引入兼容库:

import 'babel-polyfill';

{

console.log('a','\u0061');//a a

console.log('a','\u20BB7');//a ₻7 超过了0xFFF,即两个字节,会被当成两个字符

console.log('s',`\u{20BB7}`);//s 𠮷

}

{

let s='𠮷';

//es5

console.log('length',s.length);//2 (码字大于两个字节,当四个字节处理,计算长度的时候每两个字节算一个长度)

console.log('0',s.charAt(0));//0 乱码

console.log('0',s.charAt(2));//0 乱码

console.log('at0',s.charCodeAt(0));//at0 55362

console.log('at1',s.charCodeAt(1));//at0 57271

//es6

let s1='𠮷a';

console.log('length',s1.length);//3

console.log('code0',s1.codePointAt(0));//134071 取出4个字节

console.log('code0',s1.codePointAt(0).toString(16));//20bb7

console.log('code1',s1.codePointAt(1));//57271 取出后两个字节

console.log('code1',s1.codePointAt(2));//97 就是a

//.toString(16)转成16进制

}

{

//es5

console.log(String.fromCharCode('0x20BB7'));//乱码

//es6

console.log(String.fromCodePoint('0x20BB7'));//𠮷

}

{

let str='\u{20BB7}abc';

for (let i=0;i

console.log('es5',str[i]);//前两个乱码 a b c

}

for (let code of str){

console.log('es6',code);//𠮷 a b c

}

}

{

let str='string';

console.log('includes',str.includes('r'));//true

console.log('start',str.startsWith('str'));//true

console.log('end',str.endsWith('ng'));//true

}

{

let str='abc';

//es5是用+

console.log(str.repeat(2));//abcabc

}

模板字符串

{

let name='list';

let info='hello world';

let m=`i am ${name},${info}`;

console.log(m);//i am list,hello world

console.log('1'.padStart(2,'0'));//01

console.log('1'.padEnd(2,'0'));//10

}

//标签模板:放置XSS攻击,处理多语言

{

let user={

name: 'list',

info: 'hello world'

};

console.log(abc`i am ${user.name},${user.info}`);

function abc(s,v1,v2) {

console.log(s, v1, v2);//["i am ", ",", "",] "list" "hello world"

return s+v1+v2;//i am ,,,listhello world

}

}

{

console.log(String.raw`Hi\n${1-2}`);//Hi \n-1

console.log('Hi\n${1+2}');//Hi 换行 ${1+2}

}

五、数值扩展

{

console.log(0b11110111);//247 0b二进制(大小写均可)

console.log(0o11111);//4681 0o八进制(大小写均可)

}

{

console.log('15',Number.isFinite(15));//true

console.log('NaN',Number.isFinite(NaN));//false

console.log('1/0',Number.isFinite(1/0));//false

console.log('NaN',Number.isNaN(NaN));//true

console.log('0',Number.isNaN(0));//false

console.log('25',Number.isInteger(25));//true

console.log('25.0',Number.isInteger(25.0));//true 25.0=25

console.log('25.1',Number.isInteger(25.1));//false

console.log('25.0',Number.isInteger('25.0'));//false

console.log(Number.MAX_SAFE_INTEGER);

console.log(Number.MIN_SAFE_INTEGER);

console.log(Number.isSafeInteger(10));//true 是否位于上面两个数的范围内

console.log(Number.isSafeInteger('a'));//false

//es5:Math.floor,Math.ceil

console.log(4.1,Math.trunc(4.1));//4

console.log(4.9,Math.trunc(4.9));//4

console.log('-5',Math.sign(-5));//-1

console.log('5',Math.sign(5));//1

console.log('0',Math.sign(0));//0

console.log('a',Math.sign('a'));//NaN

//开立方根

console.log(Math.cbrt(-1));//-1

console.log(Math.cbrt(8));//2

}

六、数组扩展

{

let arr=Array.of(3,4,7,9,11);

console.log('arr',arr);//[3,4,7,9,11]

console.log('arr',Array.of());//[]

}

{

let p=document.querySelectorAll('p');

let pArr=Array.from(p);//将上面的集合转义成数组

pArr.forEach(function (item) {

console.log(item.textContent);

});

//map

console.log(Array.from([1,3,5],function (item) {return item+2;}));//3 5 7

//填充数组

console.log('fill-7',[1,'a',undefined].fill(7));//[7,7,7]

console.log('fill,pos',['a','b','c','d','e'].fill(7,1,3));//["a", 7, 7, "d", "e"] 1和3表示起始和截至位置,不包括位置3

for (let index of ['1','c','ks'].keys()){

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

}

for (let value of ['1','c','ks'].values()){

console.log('values',value);//1 c ks

}

for (let [index,value] of ['1','c','ks'].entries()){

console.log(index,value);

}

console.log([1,2,3,4,5].copyWithin(0,3,4));//[4,2,3,4,5] (从0开始替换,从3开始读取,也就是第一个读取的数是4,4是截至位置,也就是在位置4之前,因此只取4)

console.log([1,2,3,4,5,6].find(function (item) {

return item>3;//4,只找第一个

}));

console.log([1,2,3,4,5,6].findIndex(function (item) {

return item>3;//3

}));

console.log('number',[1,2,NaN].includes(1));//true

console.log('number',[1,2,NaN].includes(NaN));//true

}

使用扩展运算符(...)拷贝数组:const itemsCopy = [...items];

七、函数扩展

{

function test(x, y='world') {

console.log('默认值',x, y);

}

test();//undefined world

let x='test';

function test2(x,y=x) {

console.log('作用域',x,y)

}

test2('kill');//kill kill

}

{//rest参数

function test3(...arg) {//将输入的参数都转为数组

for (let v of arg){

console.log('rest',v);//a b c

}

}

test3('a','b','c');

//将数组转成离散的值

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

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

}

{//箭头函数

let arrow = v => v+2;//v是参数,v+2是返回值

console.log('arrow',arrow(3));//5

//无参数情况下

let arrow2 = ()=> 2;

}

{//伪调用:函数的最后一句话是不是函数

function tail(x) {

console.log('tail',x);

}

function fx(x) {

return tail(x);

}

fx(123);//tail 123

}

八、对象扩展

这里的对象指Object对象

{

// 简洁表达法

let o=1;

let k=2;

let es5={

o:o,

k:k

};

let es6={

o,

k

};

console.log(es5,es6);//结果是一样的

let es5_mrthod={

hello:function () {

console.log('hello');

}

};

let es6_method={

hello(){

console.log('hello');

}

};

console.log(es5_mrthod,es6_method);//结果是一样的

//属性表达式

let a='b';

let es5_obj={

a: 'c'

};

let es6_obj={

[a]:'c' //这里的a是变量,即b

};

console.log(es5_obj,es6_obj);

//新增API

console.log('字符串',Object.is('abc','abc'));//true 相当于===

console.log('数组',Object.is([],[]),[]===[]);//false false 引用地址不同

//浅复制(只改引用地址)

console.log('拷贝',Object.assign({a:'a'},{b:'b'}));//{a: "a", b:"b"}

let test={k:123,o:456};

for (let [key,value] of Object.entries(test)){

console.log(key,value);

}

}

不要声明之后又给对象添加新属性,如果一定非要加请使用Object.assign。

九、Symbol用法

Symbol的概念:用symbol声明的变量,永远不相等。

{

//声明1

let a1=Symbol();

let a2=Symbol();

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

//声明2

let a3=Symbol.for('a3');//'a3'会先检查a3是否在全局注册过,如果是,返回该值

let a4=Symbol.for('a3');

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

//使用场景

let a5=Symbol.for('abc');

let obj={

[a5]: '123',

'abc': 345,

'c': 456

};

console.log(a5,obj);//Symbol(abc) {abc: 345,c: 456, Symbol(abc): "123"}

for (let [key,value] of Object.entries(obj)){

console.log('let of',key,value);

}

//let of abc 345

//let of c 456

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

console.log(obj[item]);//123

});

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

console.log(item,obj[item]);//可以将所有的key-value值打印出来

});

}

十、set-map数据结构

数据结构:set、weakset、map、weakmap

Object的key必须是字符串或者Symbol数据类型,而map的key可以是任意数据类型。

weakset与set支持的数据类型不同,weakset的元素只能是数据对象,且weakset中的对象是弱引用(地址引用),即不会检测这个对象是否在其他地方用过,也就意味着不会和垃圾回收机制挂钩(不会检测是否被回收)。

{//set

let list=new Set();//没有重复值

list.add(5);

list.add(7);

console.log('size',list.size);//2

let arr=[1,2,3,4,5];

let list1=new Set(arr);

console.log('size',list1.size);//5

let list2=new Set();

list2.add(1);

list2.add(2);

list2.add(1);

console.log('size',list2.size);//2

//重要应用场景:去重

let arr1=[1,2,3,1,2];

let list3=new Set(arr1);

console.log('unique',list3);//{1,2,3}

let arr2=[1,2,3,1,"2"];

let list4=new Set(arr2);

console.log('unique',list4);//{1,2,3,"2"}

let arr3=['add','delete','clear','has'];

let list5=new Set(arr3);

console.log(list5.has('add'));//true

console.log('delete',list5.delete('add'),list5);//true {"delete","clear","has"}

list5.clear();

console.log(list5);//set(0)

//key和value都是一样的

let list6=new Set(arr3);

for (let key of list6.keys()){

console.log('keys',key);

}

for (let value of list6.values()){

console.log('values',value)

}

for (let value of list6.values()){

console.log('values',value)

}

for (let [key,value] of list6.entries()){

console.log(key,value)

}

list6.forEach(function (item) {

console.log(item);

});

}

{//weakset

let weakList=new WeakSet();

let arg={};

weakList.add(arg);

//weakList.add(2);//报错

console.log(weakList);

//无clear方法,无size属性,不能遍历

}

{//map

let map=new Map();

let arr=['123'];

map.set(arr,459);

console.log(map,map.get(arr));

//第二种定义方式

let map1=new Map([['a',123],['b',456]]);

console.log(map1);//{"a"=>123,"b"=>456

console.log('size',map1.size);

console.log('delete',map.delete('a'),map);

console.log('clear',map.clear(),map);

//遍历同set

}

{//weakmap

let weakMap=new WeakMap();//接收对象必须是对象

//无size对象,无clear方法,不能遍历

}

十一、map-set与数组和对象的比较

{

//map与数组的对比

let map=new Map();

let array=[];

//增

map.set('a',123);

array.push({a:123});

console.info('map-array',map, array);

//查

let map_exists=map.has('a');//true

let array_exists=array.find(item =>item.a);//{a:123}

//改

map.set('a',2);

array.forEach(item => item.a?item.a=2:'');

//删

map.delete('a');

let index=array.findIndex(item=>item.a);

array.splice(index,1);

}

{

//set和array的对比

let set=new Set();

let array=[];

//增

set.add({t:1});

//查

let set_exist=set.has({t:1});

//改

set.forEach(item=>item.t?item.t=2:'');

//删

set.forEach(item=>item.t?set.delete(item):'');

}

{

//map、set与object的区别

let item={t:1};

let map=new Map();

let set=new Set();

let obj={};

//增

map.set('t',1);

set.add(item);

obj['t']=1;

//查

console.info({

map_exists: map.has('t'),

set_exists: set.has(item),

obj_exists: 't' in obj

});

//改

map.set('t',2);

item.t = 2;//set的改,引用类型

obj['t']=2;

//删

map.delete('t');

set.delete(item);

delete obj['t'];

}

如果只是简单的key: value结构,建议优先使用Map,因为Map提供方便的遍历机制。

十二、Proxy和Reflect

{

//proxy:代理

let obj={ //原始对象,存储真实数据

time: '2017-08-04',

name: 'net',

_r: 123

};

let monitor=new Proxy(obj,{//通过Proxy新生成一个对象

//拦截对象属性的读取

get(target,key){

return target[key].replace('2017','2018');

},

//拦截对象属性的设置

set(target,key,value){

if (key === 'name') {

return target[key]=value;

}else{

return target;//不做任何操作

}

},

//拦截key in Object 操作

has(target,key){

if (key === 'name'){

return target[key];

} else{

return false;

}

},

//拦截delete操作符

deleteProperty(target,key){

if (key.indexOf('_')>-1){

delete target[key];

return true;

}else{

return target[key];

}

},

//拦截Object.keys,Object.getOwnPropertySymbols,Object.getOwnPropertNames

ownKeys(target){

return Object.keys(target).filter(item=>item!='time');

}

});

//用户使用的是monitor

console.log(monitor.time);

monitor.time='2018';

console.log(monitor.time);//没有变化

monitor.name = 'com';

console.log(monitor.name);//com

console.log('name' in monitor);//true

delete monitor['time'];

console.log(monitor);//未删除

delete monitor._r;

console.log(monitor);//删除

console.log(Object.keys(monitor));//"name"

}

{

//reflect:方法同proxy

let obj={ //原始对象,存储真实数据

time: '2017-08-04',

name: 'net',

_r: 123

};

console.log(Reflect.get(obj,'time'));//2017-08-04

Reflect.set(obj,'name','com');

console.log(obj);//com

console.log(Reflect.has(obj,'name'));//true

}

{

//使用场景:数据类型的校验(与业务解耦的校验模块)

function validator(target,validator) {

return new Proxy(target,{

_validator:validator,

set(target,key,value,proxy){

if (target.hasOwnProperty(key)){

let va=this._validator[key];

if (!!va[value]){

return Reflect.set(target,key, value,proxy);

}else{

throw Error(`不能设置${key}为${value}`);

}

}else{

throw Error(`${key}不存在`);

}

}

});

}

const personValidators={

name(val){

return typeof val === 'string';

},

age(val){

return typeof val === 'number' && val>18;

}

};

class Person{

constructor(name,age){

this.name=name;

this.age=age;

return validator(this,personValidators);

}

}

const person=new Person('lilei',30);

console.info(person);//Proxy{name:"lilei",age:30}

person.name=48;//error:不能设置name为48

}

十三、类和对象

{

//类的基本定义和生成实例

class Parent{

//es6中定义构造函数

constructor(name='com'){

this.name=name;

}

}

let v_parent=new Parent('net');

console.info(v_parent);

//继承

class Child extends Parent{

}

console.log(new Child());//{name:"com"}

//继承传递参数,将参数传递给父类

class Child2 extends Parent{

constructor(name='child'){

super(name);//super一定放在构造函数的第一行

this.type='child';

}

}

console.log(new Child2());//{name:"child",type:"child"}

//getter,setter

class Parent2{

constructor(name='com'){

this.name=name;

}

get longName(){

return 'long'+this.name;

}

set longName(value){

this.name=value;

}

}

let v_parent2=new Parent2();

v_parent2.longName='net';

console.log(v_parent2.longName);//longnet

//静态方法、静态属性

class Parent3{

constructor(name='com'){

this.name=name;

}

static tell(){//静态方法

console.log('tell');

}

}

Parent.type = 'test';//这个就是静态属性

Parent3.tell();

}

十四、Promise

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

{

//使用回调的方式

//缺点:如果是按顺序执行a,b,c...,代码的写法会非常复杂,代码的复杂影响后期的维护

let ajax=function (callback) {

console.log('执行');

setTimeout(function () {

callback&&callback.call();

},1000);

};

ajax(function () {

console.log('timeout1');

});

//使用promise解决方案

let ajax1=function () {

console.log('执行1');

return new Promise(function (resolve,reject) {

//resolve:要执行下一步的操作

//reject:要中断当前的操作

setTimeout(function () {

resolve();

},1000);

});

};

ajax1().then(function () {

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

return new Promise(function (resolve,reject) {

setTimeout(function () {

resolve();

},1000);

});

})

.then(function () {

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

});

}

{//捕获错误

let ajax=function (num) {

console.log('执行2');

return new Promise(function (resolve,reject) {

if (num>5){

resolve();

}else {

throw new Error('出错了');

}

});

};

ajax(2).then(function () {

console.log(6);

}).catch(function (err) {

console.log(err);

});

}

{//应用场景

//所有图片加载完再加载页面

function loadImg(src) {

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

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

img.src=src;

img.οnlοad=function () {//图片加载完成

resolve(img);

};

img.onerror = function () {

reject(err);

};

});

}

function showImgs(imgs) {

imgs.forEach(function (img) {

document.body.appendChild(img);

});

}

Promise.all([

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

loadImg('http://i4.buimg.com/567571/2b07ee25b08930ba.png'),

loadImg('http://i4.buimg.com/567571/2b07ee25b08930ba.png')

]).then(showImgs);

}

{//应用场景

//有一个图片加载完就添加到页面

function loadImg(src) {

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

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

img.src=src;

img.οnlοad=function () {//图片加载完成

resolve(img);

};

img.onerror = function () {

reject(err);

};

});

}

function showImgs(img) {

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

p.appendChild(img);

document.body.appendChild(p);

}

Promise.race([

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

loadImg('http://i4.buimg.com/567571/2b07ee25b08930ba.png'),

loadImg('http://i4.buimg.com/567571/2b07ee25b08930ba.png')

]).then(showImgs);

}

十五、Iterator和for...of循环

{

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:false}

}

{

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);//1 3 2 7 9 8

}

}

{//for...of

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

for (let value of arr){

console.log(value);//hello world

}

}

十六、Genertor

Genertor也是异步编程的一种解决方案,但是相对promise更高级一点。

{

let state=function* (){

while(1){

yield 'A';

yield 'B';

yield 'C';

}

};

let status=state();

console.log(status.next());//A done:false

console.log(status.next());//B done:false

console.log(status.next());//C done:false

console.log(status.next());//A done:false

console.log(status.next());//B done:false

}

{//应用场景:抽奖

let draw=function (count) {

//具体抽奖逻辑略

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

};

let residue=function* (count) {

while(count>0){

count--;

yield draw(count);

}

};

let start=residue(5);

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

btn.id='start';

btn.textContent='抽奖';

document.body.appendChild(btn);

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

start.next();

},false);

}

{//应用场景:定期向服务端获取数据,使用长轮询

let ajax=function* () {

yield new Promise(function (resolve,reject) {

setTimeout(function () {

resolve({code:0})

},200);

})

};

let pull=function () {

let generator=new ajax();

let step=generator.next();

step.value.then(function (d) {//step.value就是promise实例

if (d.code!=0) {//表示数据未更新

setTimeout(function () {

console.log('wait');

pull();

},1000);

}else{

console.log(d);

}

});

};

pull();

}

十七、Decorators

修饰器:一个函数,用来修改类的行为。

需要安装插件:npm install babel-plugin-transform-decorators-legacy --save-dev

.babelrc:"plugins":["transform-decorators-legacy"]

{

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

//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');//error: Cannot assign to read only property 'time' of object

// };

//在类外面操作必须在class前

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

target.myname='hello';//静态属性

};

@typename

class Test2{

}

console.log(Test2.myname);//hello

//第三方库修饰器的js库:core-decorators(npm install core-decorators)

}

{//应用场景:埋点

//将埋点系统从业务逻辑中拆离

let log=(type)=>{

return function (target,name,descriptor) {

let src_method=descriptor.value;

descriptor.value=(...arg)=>{

src_method.apply(target,arg);

console.info(`log ${type}`);

}

}

};

class AD{

@log('show')

show(){

console.log('ad is show');

}

@log('type')

click(){

console.log('ad is click');

}

}

let ad=new AD();

ad.show();//ad is show log show

ad.click();//ad is click log type

}

十八、模块化

ES6的模块化语法:引入import、导出export

导出:

export let A=123;

export function test() {

console.log('test');

}

export class Hello {

test(){

console.log('class');

}

}

导入:

import {A,test,Hello} from "./class/lesson17";

console.log(A, test, Hello);

可以只导入部分变量:

import {A} from "./class/lesson17";

console.log(A);

起别名:

import * as lesson from "./class/lesson17";

console.log(lesson.A);

不给导出数据起名字(推荐):

let A=123;

function test() {

console.log('test');

}

class Hello {

test(){

console.log('class');

}

}

export default {

A,

test,

Hello

}

导入:

import lesson from "./class/lesson17";

console.log(lesson.A);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值