快来围观一下JavaScript的Proxy

简介:

的确写Proxy文章很多,那么今天我也不凑字数了,炒两个栗子吧。

一、虚拟属性


  const person = {
    name: 'xiaoyun',
    province: '江苏省',
    city: '南京市'
  }

对于上述对象,我们可能需要地址信息(由省市拼接而成),在此之前我们可能会采取下列方式:

  • 直接在person对象上声明一个address属性;
  • 当用到address信息时,再通过person拼接。

第一个方法的主要弊端是污染了原有的对象,而第二种方法就很不灵活。现在我们可以通过Proxy实现比较好的效果:



  const enhancePerson = new Proxy(person, {
    get (target, name) {
      switch (name) {
        case 'address':
          return `${target['province']}-${target['city']}`
        default:
          return target[name]
      }
    }
  })
  enhancePerson.address // 江苏省-南京市

通过这种方式我们就可以实现虚拟属性了,因为它不会被遍历出来:

  Object.keys(enhancePerson) // [ 'name', 'province', 'city' ]

这里还有一个我觉得比较容易忽略的点:

 person === enhancePerson // false
  enhancePerson.city = '苏州市'
  enhancePerson.city === person.city // true

显然这两个并不是同一个对象,但是我通过改变enhancePerson的city属性却影响到了person的city属性,这就是我们通常会忽略掉的,如果你不设置Proxy的set方法,它会保持默认行为:


  set (target, propKey, value) {
    target[propKey] = value
  }

可能有些同学会想不就是不让它遍历出来吗?看这招:


  const person = {
    name: 'xiaoyun',
    province: '江苏省',
    city: '南京市',
    get address () {
      return `${this.province}-${this.city}`
    }
  }

  const enhancePerson = new Proxy(person, {
    ownKeys (target) {
      return Object.keys(target).filter(item => item !== 'address')
    }
  })

  enhancePerson.address // 江苏省-南京市
  Object.keys(enhancePerson) // [ 'name', 'province', 'city' ]

虽然是实现了上述的功能,但是Proxy中的ownKeys拦截的方法太多,所以我们拦截ownKeys之后,会导致某些方法无法使用,并且拦截ownKeys返回的结果也有严格的要求:

  • 返回的结果必须是一个数组
  • 并且数组的元素必须是String或者Symbol类型
  • 结果必须包含对象的所有不可配置、自身拥有的属性
  • 如果对象不能扩展,则结果只能包含自身拥有的属性,不能含有其他属性

所以在拦截方法注意点很多,不然很容易出现问题。

Tip: 未通过defineProperty定义的属性的描述器属性默认为true,否则默认为false。

二、扩展基本操作

当我第一次接触Python时,比较有印象的就是它的List的一个语法: arr[1:3],以前只有羡慕的份,现在完全可以自己撸一个:



 const arr = [1, 2, 3, 4, 5, 6, 7, 8]

  const list = new Proxy(arr, {
    get (target, name) {
      if (name.includes(':')) {
        const indexs = name.split(':')
        return target.slice(indexs[0], indexs[1])
      }
      return target[name]
    }
  })

  list['2:6'] // [ 3, 4, 5, 6 ]

是不是,对于对象,我们同样可以采用类似的方法:


  const obj = {
    a: {
      b: {
        c: 'xiaoyun'
      }
    }
  }

  const obj1 = new Proxy(obj, {
    get (target, name) {
      const keys = name.split('.')
      return keys.reduce((pre, next) => {
        if (pre !== null && pre !== undefined) {
          pre = pre[next]
        }
        return pre
      }, target)
    }
  })
  obj1['a.b.c'] // xiaoyun



原文发布时间为:2018年05月26日
原文作者: 云起时

本文来源: 掘金 如需转载请联系原作者



相关文章
|
2月前
|
缓存 JavaScript 数据安全/隐私保护
js开发:请解释什么是ES6的Proxy,以及它的用途。
`ES6`的`Proxy`对象用于创建一个代理,能拦截并自定义目标对象的访问和操作,应用于数据绑定、访问控制、函数调用的拦截与修改以及异步操作处理。
24 3
|
4月前
|
JSON JavaScript 前端开发
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)(下)
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)
52 2
|
3月前
|
JSON 前端开发 JavaScript
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)
40 0
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)
|
4月前
|
缓存 前端开发 JavaScript
理解 Proxy 和 Object.defineProperty:提升你的 JavaScript 技能(下)
理解 Proxy 和 Object.defineProperty:提升你的 JavaScript 技能(下)
理解 Proxy 和 Object.defineProperty:提升你的 JavaScript 技能(下)
|
4月前
|
JavaScript 前端开发 测试技术
理解 Proxy 和 Object.defineProperty:提升你的 JavaScript 技能(上)
理解 Proxy 和 Object.defineProperty:提升你的 JavaScript 技能(上)
理解 Proxy 和 Object.defineProperty:提升你的 JavaScript 技能(上)
|
4月前
|
前端开发 JavaScript
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)(上)
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)
40 2
|
7月前
|
JavaScript 前端开发 开发者
带你读《现代Javascript高级教程》十六、深入理解Proxy(1)
带你读《现代Javascript高级教程》十六、深入理解Proxy(1)
|
7月前
|
JavaScript 前端开发 C++
带你读《现代Javascript高级教程》十六、深入理解Proxy(2)
带你读《现代Javascript高级教程》十六、深入理解Proxy(2)
|
9月前
|
JavaScript
Nuxt.js 服务端渲染 axios(@nuxtjs/axios) 和 proxy 代理的配置
Nuxt.js 服务端渲染 axios(@nuxtjs/axios) 和 proxy 代理的配置
394 0
|
10月前
|
JavaScript 前端开发 开发者
《现代Javascript高级教程》深入理解Proxy
深入理解Proxy 在现代JavaScript中,Proxy是一种非常有用的特性,它允许我们在许多常规操作中插入自定义行为。然而,由于其深度和复杂性,很多开发者可能会对如何使用它或它的工作原理感到困惑。在本篇文章中,我们将详细讨论JavaScript Proxy,并通过代码示例演示其使用。
64 0