ES6之Proxy 的巧用

摘要: Proxy的骚操作。

Fundebug经授权转载,版权归原作者所有。

Proxy 介绍

使用Proxy,你可以将一只猫伪装成一只老虎。下面大约有6个例子,我希望它们能让你相信,Proxy 提供了强大的 Javascript 元编程。

尽管它不像其他ES6功能用的普遍,但Proxy有许多用途,包括运算符重载对象模拟简洁而灵活的API创建对象变化事件,甚至Vue 3背后的内部响应系统提供动力

Proxy用于修改某些操作的默认行为,也可以理解为在目标对象之前架设一层拦截,外部所有的访问都必须先通过这层拦截,因此提供了一种机制,可以对外部的访问进行过滤和修改。这个词的原理为代理,在这里可以表示由它来“代理”某些操作,译为“代理器”。

ES6原生提供了Proxy构造函数,用来生成Proxy实例。

var proxy = new Proxy(target, handler);

Proxy对象的所有用法,都是上面的这种形式。不同的只是handle参数的写法。其中new Proxy用来生成Proxy实例,target是表示所要拦截的对象,handle是用来定制拦截行为的对象。

下面是 Proxy 最简单的例子是,这是一个有陷阱的代理,一个get陷阱,总是返回42

let target = {
    x: 10,
    y: 20
};

let hanler = {
    get: (obj, prop) => 42
};

target = new Proxy(target, hanler);

target.x; //42
target.y; //42
target.x; // 42

结果是一个对象将为任何属性访问操作都返回“42”。 这包括target.xtarget['x']Reflect.get(target, 'x')等。

但是,Proxy 陷阱当然不限于属性的读取。 它只是十几个不同陷阱中的一个:

Proxy 用例

ES6之Proxy 的巧用

默认值/“零值”

在 Go 语言中,有零值的概念,零值是特定于类型的隐式默认结构值。其思想是提供类型安全的默认基元值,或者用gopher的话说,给结构一个有用的零值。

虽然不同的创建模式支持类似的功能,但Javascript无法用隐式初始值包装对象。Javascript中未设置属性的默认值是undefined。但 Proxy 可以改变这种情况。

const withZeroValue = (target, zeroValue) =>
    new Proxy(target, {
        get: (obj, prop) => (prop in obj ? obj[prop] : zeroValue)
    });

函数withZeroValue 用来包装目标对象。 如果设置了属性,则返回属性值。 否则,它返回一个默认的“零值”

从技术上讲,这种方法也不是隐含的,但如果我们扩展withZeroValue,以Boolean (false), Number (0), String (""), Object ({}),Array ([])等对应的零值,则可能是隐含的。

let pos = {
    x: 4,
    y: 19
};

console.log(pos.x, pos.y, pos.z); // 4, 19, undefined

pos = withZeroValue(pos, 0);

console.log(pos.z, pos.y, pos.z); // 4, 19, 0

此功能可能有用的一个地方是坐标系。 绘图库可以基于数据的形状自动支持2D和3D渲染。 不是创建两个单独的模型,而是始终将z默认为 0 而不是undefined,这可能是有意义的。

负索引数组

在JS中获取数组中的最后一个元素方式通过写的很冗长且重复,也容易出错。 这就是为什么有一个TC39提案定义了一个便利属性Array.lastItem来获取和设置最后一个元素。

其他语言,如Python和Ruby,使用负组索引更容易访问最后面的元素。例如,可以简单地使用arr[-1]替代arr[arr.length-1]访问最后一个元素。

使用 Proxy 也可以在 Javascript 中使用负索引。

const negativeArray = els =>
    new Proxy(els, {
        get: (target, propKey, receiver) =>
            Reflect.get(
                target,
                +propKey < 0 ? String(target.length + +propKey) : propKey,
                receiver
            )
    });

一个重要的注意事项是包含handler.get的陷阱字符串化所有属性。 对于数组访问,我们需要将属性名称强制转换为Numbers,这样就可以使用一元加运算符简洁地完成。

现在[-1]访问最后一个元素,[-2]访问倒数第二个元素,以此类推。


const unicorn = negativeArray(["
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值