Proxy对象和Reflect浅析

在这里插入图片描述

1. Proxy 对象是什么?有什么作用?

Proxy 对象用于创建一个对象的代理,从而实 现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)

const p = new Proxy(target, handler)
  • target
    要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

  • handler
    一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。

let obj = {
    name: 'Victor',
    age: 28
}
obj = new Proxy(obj, {
    get(target, key) {
        console.log("获取了getter属性");
        return target[key];
    },
    set(target, key, value) {
        if (key === "age" && typeof value !== "number") {
            throw Error("age字段必须为Number类型");
        }
        return Reflect.set(target, key, value);
    }
})

console.log(obj.name)
obj.age = false

在这里插入图片描述
在这里插入图片描述

2. Proxy 中Reflect对象的作用?为什么要用Reflect?

Reflect其实是Object对象的衍生,严格来讲,它继承了Object的大部分方法,也在许多地方做了相应的优化:

1. return不返回obj,而是返回true或者false, 这样可以避免Object.defineProperty抛出错误:
2. 更方便的函数操作
在ES5中,譬如:

  • 要判断一个obj有定义或者继承了属性name, 在ES5中这样判断:name in obj;
  • 或者删除一个属性:delete obj[name],虽然这些很好用,很简短明确,但是最好能将这些方法封装起来,统一调用;
    而有了Reflect, 它将这些方法一并封装进入该对象中:
  • Reflect.has(obj, name)
  • Reflect.deleteProperty(obj, name);
    3. 更加稳定可靠的函数调用:

在ES5中,如果需要调用一个函数f,执行上下文指向obj对象,还有args参数列表,通常是这么写:

f.apply(obj, args)

However, f could be an object that intentionally or unintentionally defines its own apply method. When you really want to make sure that the built-in apply function is called, one typically writes:
然而, 函数f可能会无意中去定义自己的apply方法。所以为了避嫌,可以这么写:

Function.prototype.apply.call(f, obj, args)

而在ES6中,可以将代码缩短:

Reflect.apply(f, obj, args)

4. 调用构造函数时可接受不确定长度的参数列表:
在ES6中可以使用拓展符:

var obj = new F(...args)

但是在ES5,这样根本行不通,如果有了Reflect,就可以这么写:

var obj = Reflect.construct(F, args)

5. 控制访问器或者读取器的this
在ES5中,访问或者定义或对象属性可以这样写:

var name = ... // get property name as a string
obj[name] // generic property lookup
obj[name] = value // generic property update

Relect也能有相应的方法,此外,还令加了一个receiver参数,用于绑定getter和setter的执行上下文:

var name = ... // get property name as a string
Reflect.get(obj, name, wrapper) // if obj[name] is an accessor, it gets run with `this === wrapper`
Reflect.set(obj, name, value, wrapper)

6. 避免直接访问 proto

ES5提供了 Object.getPrototypeOf(obj),去访问对象的原型;
而ES6提供也提供了Reflect.getPrototypeOf(obj) 和 Reflect.setPrototypeOf(obj, newProto),这个是新的方法去访问和设置对象的原型:

为什么要使用Reflect?

3. 为什么Proxy中的getter和setter函数会有receiver?

为了避免执行上下文指向出错,这里的receiver指的是 Proxy 或者继承 Proxy 的对象

Object中的getter和setter

点击此处查看详情

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值