Object.defineProperty 和 Proxy

Object.defineProperty 和 Proxy
相同点
  • 可以劫持数据,并对属性描述
  • 拥有 getter,setter 函数
  • 劫持数据类型:Object,Aarry
不同点
  • defineProperty 只能劫持对象的属性
  • defineProperty 对新增的属性劫持不到,需要手动进行 Observe
  • defineProperty 劫持数组,下标当成 key 值用(由于性能问题,vue 放弃这个特性)
    • 数组通过 pop 或 shift 删除元素,会删除并更新索引,也会触发 getter,setter 方法
    • 通过 push 或 unshift 会增加索引,新增加的索引(需要重新 Observe)
    • 插入,删除操作会使被劫持的索引发生改变,发生改变的索引会触发 getter,setter 操作
  • Proxy 直接代理对象
    • 可以监听到 Object 新增的属性
    • Proxy 劫持数组便利
    • Proxy 浏览器兼容不太好
    • Proxy 支持 13 种拦截操作
      • get(target, propKey, receiver):拦截对象属性的读取,比如 proxy.foo 和 proxy[‘foo’]。
      • set(target, propKey, value, receiver):拦截对象属性的设置,比如 proxy.foo = v 或 proxy[‘foo’] = v,返回一个布尔值。
      • has(target, propKey):拦截 propKey in proxy 的操作,返回一个布尔值。
      • deleteProperty(target, propKey):拦截 delete proxy[propKey] 的操作,返回一个布尔值。
      • ownKeys(target):拦截 Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for…in 循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而 Object.keys() 的返回结果仅包括目标对象自身的可遍历属性。
      • getOwnPropertyDescriptor(target, propKey):拦截 Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
      • defineProperty(target, propKey, propDesc):拦截 Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
      • preventExtensions(target):拦截 Object.preventExtensions(proxy),返回一个布尔值。
      • getPrototypeOf(target):拦截 Object.getPrototypeOf(proxy),返回一个对象。
      • isExtensible(target):拦截 Object.isExtensible(proxy),返回一个布尔值。
      • setPrototypeOf(target, proto):拦截 Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
      • apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如 proxy(…args)、proxy.call(object, …args)、proxy.apply(…)。
      • construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如 new proxy(…args)。
 function defineReactive(data, key, value) {
  Object.defineProperty(data, key, {
    enumerable: true,
    configurable: true,
     get: function defineGet() {
      console.log(`get key: ${key} value: ${value}`)
      return value
    },
     set: function defineSet(newVal) {
      console.log(`set key: ${key} value: ${newVal}`)
      value = newVal
    }
  })
}
function observe(data) {
  Object.keys(data).forEach(function(key) {
    defineReactive(data, key, data[key])
  })
}
let arr =[1, 2, 3]
observe(arr)
arr.splice(1,1)

输出:
get key: 1 value: 2
get key: 2 value: 3
set key: 1 value: 3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值