回顾复习set 、map
time 5m
需要有清晰认知,foreach、reduce这些方法是干什么的,返回值是什么
需要总结
map转数组
time 8m11s
用展开运算符,map结构转成数组
const myMap = new Map();myMap.set(true, 7).set({foo: 3}, ['abc']);console.log(myMap);console.log([...myMap]);

数组转成map,map([])

map转成对象
time 15m44s
map 转成对象;(条件:键名为字符串)
键名为对象,对象的键名只能是字符串,不能是对象
const map = new Map();map.set(true, 7).set({foo: 3}, ['abc']);function mapToObj(strMap) {const obj = {};// for (let {0:key, 1:value} of strMap) {for (let [key, value] of strMap) {obj[key] = value;// console.log(key,value)}return obj;}const res = mapToObj(map);console.log(res);// console.log(map);

对象转换成map
time 21m04s
map对比array
time 26m41s
map比array简单

set对比array
time 41m48s
set比array略微简单
map、set、object对比
time 53m49s


weakMap、weakSet
time 1h3m
console.log(new WeakMap());console.log(new WeakSet());

time 1h6m
let wm=new WeakSet();// wm.add(1);//Uncaught TypeError: Invalid value used in weak set/*成员只能是对象,里面的内容只能是对象*/wm.add({})//正确 可以运行wm.add([])//正确 可以运行 数组也是对象console.log(wm);

time 1h7m
let wm=new WeakMap();// wm.set('t',2)//Uncaught TypeError: Invalid value used as weak map keywm.set({t:1},2)//正确 可以运行 键名必须是一个对象,成员只能是对象console.log(wm);
这些都不是最主要区别,最主要区别是回收机制是不一样的,它是一个弱引用,垃圾回收不会考虑它们的引用。如果外界没有引用它们,直接被销毁,不考虑它的引用,直接释放
引用见闭包,被外界引用不销毁。
内存周期
time 1h9m
var o1 = {o2: {x: 1}}var o3=o1;o1=1;var o4=o3.o2;o3='123';o4=null;
o4不设置为null,持有o3.o2的引用,不会被删除
var o4=weakmap;是个弱引用,不计数为1,还是0,计数为0,可能这个成员就直接就消失了,会被垃圾回收,导致结果不稳定,不知道什么时候就被垃圾回收了,所以它不适合引用
weakmap引用时,不会记录引用次数,不会引用次数+1
不能迭代,因为有可能消失,行为不可以预知
很少会用到
proxy
time 1h18m
设计模式:代理模式
proxy是一个构造函数,es6中通过这个实现代理模式,这是代理模式的一种实现方式
概念
代码示例get方法
time 1h27m
let star = {name: 'li**',age: '25',phone: 'star 1388888888'}let agent = new Proxy(star, {get: function (target, key) {if (key === 'phone') {return 'agent:1383838438';// return target[key];}if(key==='price'){return 12000;}return target[key];}})console.log(agent.phone);//agent:1383838438console.log(agent.price);//12000console.log(agent.name);//li**console.log(agent.age);//25
/*例子,比如我想找一个明星商演,明星很忙,我得找她的经纪人,经纪人代理沟通这件事* 我直接联系不到明星本身,只能和代理人沟通,联系*/let star = {name: 'li**',age: '25',phone: 'star 1388888888'}/*代理人,用proxy封装了明星*/let agent = new Proxy(star, {/*get方法,获取方法,覆盖,重载* 读取操作,拦截的是读取操作*/get: function (target, key) {/*判断key值*/if (key === 'phone') {/*代理人不想告诉我明星的电话,我只能查到代理人的电话,代理人只给我代理人的电话,* 联系方式*/return 'agent:1383838438';/*代理人告诉明星的电话*/// return target[key];}/*明星没有的属性,也能通过代理人得知*/if (key === 'price') {return 12000;}/*名字、年龄等公开的东西,代理人也可以直接告诉,直接从明星身上取得*/return target[key];}})console.log(agent.phone);//agent:1383838438console.log(agent.price);//12000console.log(agent.name);//li**console.log(agent.age);//25console.log(agent);

set方法
time 1h38m
/*例子,比如我想找一个明星商演,明星很忙,我得找她的经纪人,经纪人代理沟通这件事* 我直接联系不到明星本身,只能和代理人沟通,联系*/let star = {name: 'li**',age: '25',phone: 'star 1388888888'}/*代理人,用proxy封装了明星*/let agent = new Proxy(star, {/*get方法,获取方法,覆盖,重载* 读取操作,拦截的是读取操作*/get: function (target, key) {/*判断key值*/if (key === 'phone') {/*代理人不想告诉我明星的电话,我只能查到代理人的电话,代理人只给我代理人的电话,* 联系方式*/return 'agent:1383838438';/*代理人告诉明星的电话*/// return target[key];}/*明星没有的属性,也能通过代理人得知*/if (key === 'price') {return 12000;}/*名字、年龄等公开的东西,代理人也可以直接告诉,直接从明星身上取得*/return target[key];},/*赋值操作*/set:function (target,key,value) {if(value<100000){throw new Error('价格太低');}else {target[key]=value;return true;}}})console.log(agent.phone);//agent:1383838438console.log(agent.price);//12000console.log(agent.name);//li**console.log(agent.age);//25// console.log(agent);agent.customPrice=150000;console.log(agent.customPrice);//150000/*agent、star都有customPrice的值*/console.log(agent);console.log(star);

has操作
time 1h44m
/*例子,比如我想找一个明星商演,明星很忙,我得找她的经纪人,经纪人代理沟通这件事* 我直接联系不到明星本身,只能和代理人沟通,联系*/let star = {name: 'li**',age: '25',phone: 'star 1388888888'}/*代理人,用proxy封装了明星*/let agent = new Proxy(star, {/*get方法,获取方法,覆盖,重载* 读取操作,拦截的是读取操作*/get: function (target, key) {/*判断key值*/if (key === 'phone') {/*代理人不想告诉我明星的电话,我只能查到代理人的电话,代理人只给我代理人的电话,* 联系方式*/return 'agent:1383838438';/*代理人告诉明星的电话*/// return target[key];}/*明星没有的属性,也能通过代理人得知*/if (key === 'price') {return 12000;}/*名字、年龄等公开的东西,代理人也可以直接告诉,直接从明星身上取得*/return target[key];},/*赋值操作*/set: function (target, key, value) {if (value < 100000) {throw new Error('价格太低');} else {target[key] = value;return true;}},/*监听了一个in操作符*/has: function (target, key) {console.log('请联系agent:1383838438');if (key === 'customPrice') {return target[key];} else {return false;}}})console.log(agent.phone);//agent:1383838438console.log(agent.price);//12000console.log(agent.name);//li**console.log(agent.age);//25// console.log(agent);agent.customPrice = 150000;console.log(agent.customPrice);//150000/*agent、star都有customPrice的值*//* console.log(agent);console.log(star);*/console.log('customPrice' in agent);//true booleanconsole.log('price' in agent);//false/*不打印请联系agent:1383838438,说明has没有运行* for in时has不运行* has 没办法拦截 for in*/for (let key in agent) {console.log(agent[key]);}
reflect
time 1h54m
console.log(Reflect);

一般用不到
/*例子,比如我想找一个明星商演,明星很忙,我得找她的经纪人,经纪人代理沟通这件事* 我直接联系不到明星本身,只能和代理人沟通,联系*/let star = {name: 'li**',age: '25',phone: 'star 1388888888'}/*代理人,用proxy封装了明星*/let agent = new Proxy(star, {/*get方法,获取方法,覆盖,重载* 读取操作,拦截的是读取操作*/get: function (target, key) {/*判断key值*/if (key === 'phone') {/*代理人不想告诉我明星的电话,我只能查到代理人的电话,代理人只给我代理人的电话,* 联系方式*/return 'agent:1383838438';/*代理人告诉明星的电话*/// return target[key];}/*明星没有的属性,也能通过代理人得知*/if (key === 'price') {return 12000;}/*名字、年龄等公开的东西,代理人也可以直接告诉,直接从明星身上取得*/return target[key];},/*赋值操作*/set: function (target, key, value) {if (value < 100000) {throw new Error('价格太低');} else {target[key] = value;return true;}},/*监听了一个in操作符*/has: function (target, key) {console.log('请联系agent:1383838438');if (key === 'customPrice') {return target[key];} else {return false;}},/*拦截delete操作*/deleteProperty:function (target, key) {if(key.indexOf("_")===0){delete target[key];}},/* ownKeys:function (target) {console.log(1);console.log(target);}*/})console.log(agent.phone);//agent:1383838438console.log(agent.price);//12000console.log(agent.name);//li**console.log(agent.age);//25// console.log(agent);agent.customPrice = 150000;console.log(agent.customPrice);//150000/*agent、star都有customPrice的值*//* console.log(agent);console.log(star);*/console.log('customPrice' in agent);//true booleanconsole.log('price' in agent);//false/*不打印请联系agent:1383838438,说明has没有运行* for in时has不运行* has 没办法拦截 for in*/for (let key in agent) {console.log(agent[key]);}
一般只用get、set、has、deleteProperty这几个操作
使用
time 1h58m
var obj = {a: 1,b: 2,c: 3}// console.log(Reflect);console.log(Reflect.get(obj,'a'));//1
Reflect映射响应的一系列方法,Reflect其实就是一种简便的写法,以前通过操作符来定义,现在通过函数来定义,语义化更好

es5
Object.defineProperty
通过简便的方式,比上面用Object简单,减少歧义,认为这样更加合理,了解就行
es6
Reflect.defineProperty
time 2h8m
本质上把Object上的方法移动到了Reflect上,并且做了异常处理
原本是Object操作符,现在Reflect把它变成了函数行为
