十一.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);//