ES6-16【WeakMap与WeakSet、proxy与reflect】

一、WeakMap与WeakSet(了解)

(1)WeakMap/WeakSet与map/set区别

  1. 和map/set基本完全一致,可以理解成阉割版的map/set,为什么是阉割?看一下其原型:

    1. weakMap原型

      WeakMap {}
      [[Entries]]
      No properties
      [[Prototype]]: WeakMap
      constructor: ƒ WeakMap()
      delete: ƒ delete()
      get: ƒ ()
      has: ƒ has()
      set: ƒ ()
      Symbol(Symbol.toStringTag): "WeakMap"
      [[Prototype]]: Object
      
    2. weakSet原型

      WeakSet {}
      [[Entries]]
      No properties
      [[Prototype]]: WeakSet
      add: ƒ add()
      constructor: ƒ WeakSet()
      delete: ƒ delete()
      has: ƒ has()
      Symbol(Symbol.toStringTag): "WeakSet"
      [[Prototype]]: Object
      

    发现map/set上的遍历方法全都没有了,所以说是阉割版

  2. 存储的成员只能是对象

    let ws = new WeakSet();
    ws.add(1); // 报错
    ws.add({'t':1}); // WeakSet {{t:1}}
    let wm = new WeakMap();
    wm.set('t',1); // 报错
    wm.set({'t':1},1); // WeakMap {{…} => 1}
    
  3. 回收机制不一样,它们属于弱引用,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; //象征性操作,说明赋值成功
        }
    },
    // 拦截 in 操作符
    has:function(target,key){
        console.log('请联系agent')
        if(key === 'customPrice'){
            return target[key]
        }else{
            return false;
        }
    },
    // 拦截 delete 操作
    deleteProperty: function(target, key){ 
    	if (key.indexof('_') === 0){ 
    		delete target [key];
    		return false;
    	}
    },
    // 拦截 getOwnPropertyNames、getOwnPropertySymbols、keys 操作
    ownKeys: function(target) {
	    console.log(1);
	    console.log(target);
	    return []; // 不返回数组会报错
	},
    // ... 还可以拦截其它,Reflect上有的方法都可在这里配置
})
console.log(agent.phone)//agent: 1281234567
console.log(agent.price)//12000
console.log(agent.name)//li**
console.log(agent.age)//25
agent.customPrice = 1500000; //1500000
console.log(agent.customPrice); //1500000
console.log('customPrice' in agent); //请联系agent false
//has是没有办法拦截for in的
for(let key in agent) {
	console.log(agent[key]);
}
console.log(delete agent.name); //false 拦截了删除
console.log(Object.getOwnPropertyNames(agent)); 
//1 {name: 'li**', age: '25', phone: 'star 128888888888'} []

其他代理操作:

  1. get(target, propKey, receiver):拦截对象属性的读取,比如 proxy.foo 和 proxy[‘foo’]
  2. set(target.propKey, value, receiver):拦截对象属性的设置,比如 proxy.foo=v 或 proxy[‘foo’]=v,返回你赋的值
  3. has(target, propKey):拦截 propKey in proxy的操作,返回一个布尔值
  4. deleteProperty(target, propKey):delete proxy[propKey]的操作,返回一个布尔值
  5. ownKeys(target):Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、 Object.keys(proxy),返回一个数组,该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性
  6. getOwnPropertyDescriptor(target, propKey):拦截 Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
  7. defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值
  8. preventExtensions(target):拦截 Object.preventExtensions(proxy),返回一个布尔值
  9. getPrototypeOf(target):拦截 Object.getPrototypeOf(proxy),返回一个对象
  10. isExtensible(target):拦截 Object.isExtensible(proxy),返回一个布尔值
  11. setPrototypeOf(target, proto):拦截 Object.setPrototypeOf(proxy, proto),返回一个布尔值,如果目标对象是函数,那么还有两种额外操作可以拦截。
  12. apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如 proxy(…args)、 proxy.call(object,…args)、proxy.apply(…)
  13. 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 /* , targetKey */)
deleteProperty: ƒ deleteProperty()
enumerate: ƒ enumerate(target)
get: ƒ ()
getMetadata: ƒ getMetadata(metadataKey, target /* , targetKey */)
getMetadataKeys: ƒ getMetadataKeys(target /* , targetKey */)
getOwnMetadata: ƒ getOwnMetadata(metadataKey, target /* , targetKey */)
getOwnMetadataKeys: ƒ getOwnMetadataKeys(target /* , targetKey */)
getOwnPropertyDescriptor: ƒ getOwnPropertyDescriptor()
getPrototypeOf: ƒ getPrototypeOf()
has: ƒ has()
hasMetadata: ƒ hasMetadata(metadataKey, target /* , targetKey */)
hasOwnMetadata: ƒ hasOwnMetadata(metadataKey, target /* , targetKey */)
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); //配置错误返回false
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值