十一.Proxy和Reflect(Proxy保护对象不被外界访问;Object方法移植到Reflect)
①Proxy:原始对象(供应商)通过Proxy(代理商)生成新对象(映射原对象),用户访问的是新对象,对新对象操作会通过Proxy传回原对象,原对象对用户不可见。
{ let obj={ time:'2017-03-11', name:'net', _r:123 }; let monitor=new Proxy(obj,{ // 拦截对象属性的读取 get(target,key){ return target[key].replace('2017','2018') }, // 拦截对象设置属性 set(target,key,value){ if(key==='name'){ return target[key]=value; }else{ return target[key]; } }, // 拦截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.getOwnPropertyNames ownKeys(target){ return Object.keys(target).filter(item=>item!='time') } }); console.log('get',monitor.time);//get 2018-03-11 monitor.time='2018'; monitor.name='mu'; console.log('set',monitor.time,monitor);//set 2018-03-11 Proxy{time: "2017-03-11", name: "mu", _r: 123} console.log('has','name' in monitor,'time' in monitor);//has true false time被隐藏了 console.log('ownKeys',Object.keys(monitor));//ownKeys ["name", "_r"] time被隐藏了 delete monitor._r; console.log('delete',monitor);//Proxy{time: "2017-03-11", name: "mu"} }
②Reflect直接用
{ let obj={ time:'2018-11-27', name:'net', _r:123 }; console.log(Reflect.get(obj,'time'));//2018-11-27 Reflect.set(obj,'name','muu'); console.log(obj);//{time: "2018-11-27", name: "muu", _r: 123} console.log(Reflect.has(obj,'name'));//ture }
十二.类
基本语法 类的继承 静态方法 静态属性 getter setter
{ // 基本定义和生成实例 class Parent{ constructor(name='muu'){ this.name=name; } } let v_parent = new Parent('v'); console.log('构造函数和实例',v_parent);//构造函数和实例 Parent {name: "v"} } { // 继承 class Parent{ constructor(name='muu'){ this.name=name; } } class Child extends Parent{ } console.log('继承',new Child());//继承 Child {name: "muu"} } { // 继承传递参数 class Parent{ constructor(name='muu'){ this.name=name; } } class Child extends Parent{ constructor(name='child'){ super(name);//一定要放在构造函数第一行 this.type='child'; } } console.log('继承传递参数',new Child('hello'));//继承传递参数 Child {name: "hello", type: "child"} } { // getter,setter class Parent{ constructor(name='muu'){ this.name=name; } get longName(){ return 'mu'+this.name } set longName(value){ this.name=value; } } let v=new Parent(); console.log('getter',v.longName);//getter mumuu v.longName='hello'; console.log('setter',v.longName);//setter muhello } { // 静态方法 class Parent{ constructor(name='muu'){ this.name=name; } static tell(){ console.log('tell'); } } Parent.tell();//tell 通过类调用而不是通过实例调用 } { // 静态属性 class Parent{ constructor(name='muu'){ this.name=name; } static tell(){ console.log('tell'); } } Parent.type='test'; console.log('静态属性',Parent.type);//静态属性 test }
十三.Promise(异步编程的解决方法,a执行完再执行b)
优点:Promise可以异步执行多个,code简洁
{ // 传统回调基本定义 打印执行,1秒后打印timeout1 let ajax=function(callback){ console.log('执行'); setTimeout(function () { callback&&callback.call() }, 1000); }; ajax(function(){ console.log('timeout1'); }) } { //打印执行2,1秒后打印promise timeout2 let ajax=function(){ console.log('执行2'); return new Promise(function(resolve,reject){ setTimeout(function () { resolve() }, 1000); }) }; ajax().then(function(){//ajax()是一个promise实例,可有很多then方法 console.log('promise','timeout2'); }) } { let ajax=function(num){ console.log('执行3'); return new Promise(function(resolve,reject){ if(num>5){ resolve() }else{ throw new Error('出错了') } }) } ajax(6).then(function(){//执行3 log 6 console.log('log',6); }).catch(function(err){ console.log('catch',err); }); ajax(3).then(function(){//执行3 catch Error: 出错了 console.log('log',3); }).catch(function(err){ console.log('catch',err); }); }
十四.Iterator和for...of循环
①Iterator接口:用一种办法读取不同的数据集合(数组、Object、Map、Set)
{ 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} } { //自定义读取 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方法的对象
next(){ if(index<len){ 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不断调用Iterator
{ //for...of 用法 let arr=['hello','world']; for(let value of arr){ console.log(value);//hello world } }
十五.Generator(异步编程)
进入函数停在第一个yield前,执行一个next()方法,执行一个yield,直到没有可往下执行的yield或者return则返回done:true
{ // genertaor基本定义 let tell = function* (){ yield 'a'; yield 'b'; return 'c' }; let k = tell(); console.log(k.next());//{value: "a", done: false} console.log(k.next());//{value: "b", done: false} console.log(k.next());//{value: "c", done: true} console.log(k.next());//{value: undefined, done: true} } { //用genertaor部署,不手写Iterator(object对象不能用for...of除非有Iterator接口) let obj={}; obj[Symbol.iterator]=function* (){ yield 1; yield 2; yield 3; } for(let value of obj){ console.log(value);//1 2 3 } } { //状态机,可以不断查找状态 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} }
十六.Decorator(修饰器:函数修改类的行为)
{ //只读 let readonly=function(target,name,descriptor){ descriptor.writable=false; return descriptor }; class Test{ @readonly time(){ return '2018-11-27' } } let test=new Test(); console.log(test.time());//2018-11-27 test.time=function(){ console.log('reset time'); }; console.log(test.time());//2018-11-27 } { let typename=function(target,name,descriptor){ target.myname='hello'; } @typename//可以放class上面 class Test{ } console.log('类修饰符',Test.myname);//类修饰符 hello //可引入第三方库修饰器的js库,不用自己写,直接@就可以:core-decorators; npm install core-decorators }
十七.模块化
export let A=123; export function test(){ console.log('test'); } export class Hello{ test(){ console.log('class'); } } import {A,test,Hello} from './xx';//{}中取什么写什么,./xx是上面内容的路径 import *as lesson1 from './xx';//取所有内容放到对象lesson1中 ------------------------------------------- let A=123; let test=function(){ console.log('test'); } class Hello{ test(){ console.log('class'); } } export default {A,test,Hello}//导出,但是我不指定名字,路径为./xxx import lesson from './xxx';//我随便叫lesson,它接收了上面的内容 console.log(lesson.A);//123