一、WeakMap与WeakSet(了解)
(1)WeakMap/WeakSet与map/set区别
-
和map/set基本完全一致,可以理解成阉割版的map/set,为什么是严格?看一下其原型:
-
weakMap原型 WeakMap {}
[[Entries]]
No properties
[[Prototype]]: WeakMap
constructor: ? WeakMap()
delete: ? delete()
get: ? ()
has: ? has()
set: ? ()
Symbol(Symbol.toStringTag): "WeakMap"
[[Prototype]]: Object
-
weakSet原型 WeakSet {}
[[Entries]]
No properties
[[Prototype]]: WeakSet
add: ? add()
constructor: ? WeakSet()
delete: ? delete()
has: ? has()
Symbol(Symbol.toStringTag): "WeakSet"
[[Prototype]]: Object
发现map/set上的遍历方法全都没有了,所以说是阉割版
-
存储的成员只能是对象 let ws = new WeakSet();
ws.add(1);
ws.add({'t':1});
let wm = new WeakMap();
wm.set('t',1);
wm.set({'t':1},1);
-
回收机制不一样,它们属于弱引用,JS垃圾回收不会考虑它们的引用
不能遍历,是因为成员都是弱引用,随时可能消失,遍历不能保证成员的存在,可能刚刚遍历结束,成员就取不到了。
二、proxy与reflect
(1)proxy
代理,即对操作符进行拦截处理
let star = {
name :'li**',
age:'25',
phone:'star 128888888888'
}
let agent = new Proxy(star,{
get:function(target,key){
if(key === 'phone'){
return 'agent: 1281234567'
}
if(key === 'price'){
return 12000
}
return target[key]
},
set:function(target,key,value){
if(value < 10000){
throw new Error('价格太低')
}else{
target[key] = value;
return true;
}
},
has:function(target,key){
console.log('请联系agent')
if(key === 'customPrice'){
return target[key]
}else{
return false;
}
},
deleteProperty: function(target, key){
if (key.indexof('_') === 0){
delete target [key];
return false;
}
},
ownKeys: function(target) {
console.log(1);
console.log(target);
return [];
},
})
console.log(agent.phone)
console.log(agent.price)
console.log(agent.name)
console.log(agent.age)
agent.customPrice = 1500000;
console.log(agent.customPrice);
console.log('customPrice' in agent);
for(let key in agent) {
console.log(agent[key]);
}
console.log(delete agent.name);
console.log(Object.getOwnPropertyNames(agent));
其他代理操作:
get(target, propKey, receiver) :拦截对象属性的读取,比如 proxy.foo 和 proxy[‘foo’]set(target.propKey, value, receiver) :拦截对象属性的设置,比如 proxy.foo=v 或 proxy[‘foo’]=v,返回你赋的值has(target, propKey) :拦截 propKey in proxy的操作,返回一个布尔值deleteProperty(target, propKey) :delete proxy[propKey]的操作,返回一个布尔值ownKeys(target) :Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、 Object.keys(proxy),返回一个数组,该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性- getOwnPropertyDescriptor(target, propKey):拦截 Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
defineProperty(target, propKey, propDesc) :拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值preventExtensions(target) :拦截 Object.preventExtensions(proxy),返回一个布尔值- getPrototypeOf(target):拦截 Object.getPrototypeOf(proxy),返回一个对象
isExtensible(target) :拦截 Object.isExtensible(proxy),返回一个布尔值setPrototypeOf(target, proto) :拦截 Object.setPrototypeOf(proxy, proto),返回一个布尔值,如果目标对象是函数,那么还有两种额外操作可以拦截。apply(target, object, args) :拦截 Proxy 实例作为函数调用的操作,比如 proxy(…args)、 proxy.call(object,…args)、proxy.apply(…)construct(target, args) :拦截 Proxy 实例作为构造a数调用的操作,比如 new proxy(…args)
(2)reflect
把一系列的操作符变成了一种函数的行为,和函数调用没什么区别
Reflect {defineProperty: ?, deleteProperty: ?, apply: ?, construct: ?, get: ?, …}
apply: ? apply()
construct: ? construct()
defineMetadata: ? defineMetadata(metadataKey, metadataValue, target, targetKey)
defineProperty: ? defineProperty()
deleteMetadata: ? deleteMetadata(metadataKey, target )
deleteProperty: ? deleteProperty()
enumerate: ? enumerate(target)
get: ? ()
getMetadata: ? getMetadata(metadataKey, target )
getMetadataKeys: ? getMetadataKeys(target )
getOwnMetadata: ? getOwnMetadata(metadataKey, target )
getOwnMetadataKeys: ? getOwnMetadataKeys(target )
getOwnPropertyDescriptor: ? getOwnPropertyDescriptor()
getPrototypeOf: ? getPrototypeOf()
has: ? has()
hasMetadata: ? hasMetadata(metadataKey, target )
hasOwnMetadata: ? hasOwnMetadata(metadataKey, target )
isExtensible: ? isExtensible()
metadata: ? metadata(metadataKey, metadataValue)
ownKeys: ? ownKeys()
preventExtensions: ? preventExtensions()
set: ? ()
setPrototypeOf: ? setPrototypeOf()
Symbol(Symbol.toStringTag): "Reflect"
[[Prototype]]: Object
var obj = {
a: 1
};
Reflect.get(obj,'a');
Reflect.set(obj,'b',10);
Reflect.has(obj,'a');
Object.defineProperty(target,property,atrributes);
Reflect.defineProperty(target,property,atrributes);
|