回顾复习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 key
wm.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:1383838438
console.log(agent.price);//12000
console.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:1383838438
console.log(agent.price);//12000
console.log(agent.name);//li**
console.log(agent.age);//25
console.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:1383838438
console.log(agent.price);//12000
console.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:1383838438
console.log(agent.price);//12000
console.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 boolean
console.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:1383838438
console.log(agent.price);//12000
console.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 boolean
console.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把它变成了函数行为