资讯专栏INFORMATION COLUMN

Proxy 的巧用

FreeZinG / 2421人阅读

摘要:为了保证的可读性,本文采用意译而非直译。对象的所有用法,都是上面的这种形式。其中用来生成实例,是表示所要拦截的对象,是用来定制拦截行为的对象。虽然不同的创建模式支持类似的功能,但无法用隐式初始值包装对象。

为了保证的可读性,本文采用意译而非直译。

想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你!

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 陷阱当然不限于属性的读取。 它只是十几个不同陷阱中的一个:

handler.get

handler.set

handler.has

handler.apply

handler.construct

handler.ownKeys

handler.deleteProperty

handler.defineProperty

handler.isExtensible

handler.preventExtensions

handler.getPrototypeOf

handler.setPrototypeOf

handler.getOwnPropertyDescriptor

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(["           
               
                                           
                       
                 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75424.html

相关文章

  • Proxy 巧用

    摘要:为了保证的可读性,本文采用意译而非直译。对象的所有用法,都是上面的这种形式。其中用来生成实例,是表示所要拦截的对象,是用来定制拦截行为的对象。虽然不同的创建模式支持类似的功能,但无法用隐式初始值包装对象。 为了保证的可读性,本文采用意译而非直译。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! Proxy 介绍 使用Proxy,你可以将一只猫伪装成一只老虎。下面大...

    feng409 评论0 收藏0
  • CSS(一)伪元素巧用

    摘要:并且,一些伪元素可以使开发者获取到不存在于源文档中的内容比如常见的还可以为伪元素定制样式。。中新增加的伪元素必须用伪类使用一个冒号例如。就本文而言,我们将把我们探讨的范围限制在和这两个伪元素的巧用上。 作为一门前端er,你肯定熟知 a:hover     a:visited.....我还记得在小本本上记着诀窍:love 与 hate 纠缠不休,大家都懂的吧。。。。        伪类和...

    entner 评论0 收藏0
  • 异或运算巧用 → 不用额外的变量,如何交换两个变量的值?

    摘要:开心一刻两头奶牛在一起吃草,其中一头奶牛甲越吃越慢,一副若有所思的模样,另一头奶牛奶牛乙发觉了,开始了对话奶牛乙搁那合计啥呢奶牛甲你帮我合计合计奶牛乙咋地了奶牛甲我吃的是草,挤出来的是奶,也就是说我把没用的变成有用的了奶牛乙是这个事奶牛甲人开心一刻  两头奶牛在一起吃草,其中一头(奶牛甲)越吃越慢,一副若有所思的模样,另一头奶牛(奶牛乙)发觉了,开始了对话  奶牛乙:搁那合计啥呢?  奶牛甲...

    不知名网友 评论0 收藏0
  • CSS3-transition常用属性及示例

    摘要:主要用来指定浏览器的过渡速度,以及过渡期间的操作进展情况,解释下注意值可以中定义自己的值,如过渡效果开始前的延迟时间,单位秒或者毫秒与的巧用示例元素上浮示例元素上浮后续还会继续补充,真心强大transition参数 语法 transition: property duration timing-function delay transition属性是个复合属性,她包括以下几个子属性: ...

    derek_334892 评论0 收藏0
  • 巧用代理设计模式(Proxy Design Pattern)改善前端图片加载体验

    摘要:我们用一些前端框架的这个控件类去显示图片。如果直接调用控件类的代码那么在这张具体的图片真正加载到本地之前,上显示一片空白,这个用户体验不好。 这篇文章介绍一种使用代理设计模式(Proxy Design Pattern)的方法来改善您的前端应用里图片加载的体验。 假设我们的应用里需要显示一张尺寸很大的图片,位于远端服务器。我们用一些前端框架的Image这个控件类去显示图片。如果直接调用控...

    dackel 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<