摘要: 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 用例

默认值/“零值”

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

ES6之Proxy 的巧用的更多相关文章

  1. ES6的Proxy

    最近在Javascript的设计编程中,用到的那个单例模式,感觉就类似一种代理的思想[其实就是缓存的一种机制],单例模式就是: function getSingle(fn){ var result; ...

  2. 详解es6中Proxy代理对象的作用

    在es6中新添加了Proxy,那么它有什么作用啊?Proxy本意为代理,而es6中的Proxy也就是代理对象,那么代理对象感觉听起来很模糊,在这里就解释一下Proxy代理对象的作用. Proxy的主要 ...

  3. [每日一题]面试官问:谈谈你对ES6的proxy的理解?

    [每日一题]面试官问:谈谈你对ES6的proxy的理解? 关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...

  4. 深度揭秘ES6代理Proxy

    最近在博客上看到关于ES6代理的文章都是一些关于如何使用Proxy的例子,很少有说明Proxy原理的文章,要知道只有真正掌握了一项技术的原理,才能够写出精妙绝伦的代码,所以我觉得有必要写一篇关于深刻揭 ...

  5. ES6之Proxy及Proxy内置方法

    Proxy是ES6提供的代理器可以起到拦截作用,写法形式如 var proxy = new Proxy(target,handler);参数target表示要拦截的目标对象,handler是用来定制拦 ...

  6. es6之Proxy,Reflect

    Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写. var proxy = new Proxy(ta ...

  7. ES6 之 Proxy

    概述 Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改. Proxy 可以理解在目标对象架设一个“拦截”层外界对该对象的访问都必须先通过这层拦截,因此提供了一种机制可以对外界的访问进行 ...

  8. ES6的Proxy和Reflect

    Proxy 有一个原始的数据对象,通过代理出来一个新的对象,用户操作的是这个新的对象 { let obj ={ time:'2018-01-01', name:'lx' , _r:123 } let ...

  9. es6(11)--Proxy,Reflect

    //Proxy,Reflect { let obj={ time:'2018-06-25', name:'net', _r:123 }; let monitor = new Proxy(obj,{ / ...

随机推荐

  1. SQL Server阻塞的检查

    1. 阻塞   除了内存.CPU.I/O这些系统资源以外,阻塞和死锁是影响数据库应用性能的另一大因素. 所谓的「阻塞」,是指当一个数据库会话中的事务,正在锁定其他会话事务想要读取或修改的资源,造成这些 ...

  2. 数据库 OR 运维 ____bayaim

    最近一直在思考,想想未来的道路和自己努力的方向.马云曾说过现在的年轻人缺少“慢下来”,只有人慢下来才能更好思考,想好方法和目标才更靠近才成功.如果,一直不停的努力,在错误的道路越走越远,势必会浪费时间 ...

  3. CUDA -- 规约求矩阵的行和

    求矩阵每行的和? 可以把每行放入一个不同线程块,这样行与行之间进行粗粒度的并行.而对于每行,其对应的线程块中分配n个线程(对应行宽),使用共享存储器,让每个线程从显存中读取一个数至shared mem ...

  4. Linux学习(一)简介

    Linux 简介 Linux 内核最初只是由芬兰人林纳斯·托瓦兹(Linus Torvalds)在赫尔辛基大学上学时出于个人爱好而编写的. Linux 是一套免费使用和自由传播的类 Unix 操作系统 ...

  5. Oracle SQL日期及日期格式获取命令

    日期及日期格式: 获取系统日期: sysdate() 格式化日期 to_char(sysdate(),'yyyy-mm-dd,hh24:mi:ss') to_date(sysdate(),'yyyy- ...

  6. Html学习之四(页面布局)

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. 计算多个点中距离最远的两个点 python

    import numpy as npfrom scipy import spatial print("hello")# test pointspts = np.random.ran ...

  8. 浅谈C++ STL deque 容器

    浅谈C++ STL deque 容器 本篇随笔简单介绍一下\(C++STL\)中\(deque\)容器的使用方法及常见使用技巧. deque容器的概念 \(deque\)的意义是:双端队列.队列是我们 ...

  9. Java中怎么合理的使用redis?

    redis 支撑许多言语的客户端.在官方网站上有支撑的一切的 [redis 客户端列表]. 因为往常运用 java 作为开发言语,所以这儿描绘一下怎样通过 java 来联接和操作 redis 服务器. ...

  10. 【2019.8.9 慈溪模拟赛 T1】数论(a)(打表找规律)

    莫比乌斯反演 血亏! 比赛时看到这题先写了个莫比乌斯反演,然后手造了几组数据和暴力对拍的时候发现,居然答案就是\(nm\)... 吐槽数据范围太小... 下面给上出题人对此题的解释: 原式的物理意义, ...