Proxy

Object.defineProperty

缺陷:
1. 设计的初衷不是为了监听一个对象中的所有属性,初衷是定义普通的属性
2. 无法对新增属性、删除属性进行监听

Proxy 代理对象

/*
const p = new Proxy(obj,{})
*/
const obj = {
    name:'hyf',
    age:18,
    height:1.88
}

const p = new Proxy(obj,{
    set:function(target,key,newValue){
        target[key] = newValue
    },
    get: function(target,key){
        return target[key]
	},
    has:function(target,key){
        return key in target
	},
    deleteProperty: function(target,key){
        delete target[key]
    },
})

console.log(p.name)
p.name = 'myl'
console.log(p.name)
function Foo(){}

let fooProxy = new Proxy(Foo,{
    // 监听函数apply
    apply(target,thisArg,otherArgs){
        return target.apply(thisArg,otherArgs)
    },
    // 监听函数new
    construct(target,argArray,newTarget){
        return new target()
    }
})

fooProxy.apply()
new fooProxy()

捕获器

  • get(target,key,):属性读取操作的捕获器
  • set(target,key,newValue,):属性读取操作的捕获器
  • has(target,key,) : in 操作符的捕获器
  • deleteProperty(target,key,):delete操作符的捕获器

Reflect

操作JavaScript对象的方法,类似Object操作对象的方法。
为什么出现?
1. 早期没有考虑到对对象本身操作如何设计更加规范,全部放到Object上
2. Object是一个构造函数,放在Object上不合适
3. 类似in/delete,会让js开起来有些奇怪
4. 因此ES6新增Reflect对象,让这些操作集中到Reflect上
5. 在使用Proxy时,可以做到不操作原对象

常见方法

  • Reflect.has(target,prop)
  • Reflect.get(target,prop,[receiver])
  • Reflect.set(target,prop,value,[receiver])
  • Reflect.deleteProperty(target,prop)
const obj = {
    name:'hyf',
    age:18,
    height:1.88
}

const p = new Proxy(obj,{
    set:function(target,key,newValue,receiver){
        // 1. 不再直接操作原对象
        // 2. 可以获取是否操作成功
        // 3. receiver就是外存Proxy对象 p===receiver
        let flag = Reflect.set(target,key,newValue,receiver)
        if (!flag) {
            throw new Error('修改失败')
        }
    },
    get: function(target,key,receiver){
        return Reflect.get(target,key,receiver)
	},
})
/*
receiver: 改变obj中getter/setter访问器中的this指向
obj = {
	_name:'ds',
	set name(value){
		this._name = value
	},
	get name(){
		return this._name
	}
}
*/
/*
Reflect.construct(Super,[args],Student)   Super.apply(this,[args])
创建的是Student类型,执行的是Super中的代码
*/
posted @ 2023-03-25 23:53  转角90  阅读(25)  评论(0编辑  收藏  举报