obj.defineProperty和Proxy的区别

obj.defineProperty

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。IE8不兼容。

Object.defineProperty(obj,prop,desc)
# 参数
   # obj:要定义属性的对象
   # prop:要定义或者修改的属性的名称或者是Symbol
   # desc:要定义或修改的属性描述符

属性值:

对象中目前存在的属性描述符有主要的两种形式:数据描述符存取描述符

数据描述符:是一个具有值得属性,该值是可写的,也是不可写的

存取描述符:是由get和set函数所描述的属性

这两种描述符都是对象,他们共享

注意:当定义了value或writeable,一定不能有get或set,当定义get或set是,不能出现writeable属性等,否则就会报错

    window.PI = 3.14
    let _PI = window.PI
// 实现一个常量 第一个参数是定义哪个对象,第二个是定义的什么属性,第三个就是定义options
    Object.defineProperty(window,"PI",{
        // writable:true,    // 设置属性是否可以修改
        // value:3.1415926,  // 设置属性的值
        // configurable:false, // 设置属性是否可以删除
        // enumerable:false,     // 设置属性是否可以遍历
        get() {
            // 是属性被访问时,触发的方法
            console.log(_PI)
            return _PI
        },
        // 在设置属性或者修改属性时,进行触发set
        set(value) {
            throw new Error("PI不可以修改")
            console.log(value)
            _PI = value
        }
    })

默认值:

configurable:当且仅当该属性的configurable键值为true时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除,默认情况下为false

enumerable:当且仅当该属性的enumerable键值为true时,该属性才会出现在对象的枚举属性中,默认为false

数据描述符具有以下可选键值:

value:该属性对应的值,可以是任何有效的javascript值(数值,对象,函数等),默认为undefined

writeable:当且仅当该属性的writeable简直为true时,属性的值,也就是上边的value值才可以被赋值运算符修改,默认时false

存取描述符还具有以下的可选键值:

get:属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。默认为 undefined

set:属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。默认为 undefined。

Object.defineProperties

Object.defineProperties本质上定义了obj 对象上props的可枚举属性相对应的所有属性。

var obj = {};
Object.defineProperties(obj, {
  'property1': {
    value: true,
    writable: true
  },
  'property2': {
    value: 'Hello',
    writable: false
  }
  // etc. etc.
});

Proxy

Proxy 对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)。IE不兼容

const p = new Proxy(target, handler)

参数
target: 要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler: 一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。

返回值
一个Proxy代理的对象,操作这个对象会触发handler对应操作。改变原始对象不会触发。

handler 对象的方法:handler 对象是一个容纳一批特定属性的占位符对象。它包含有 Proxy 的各个捕获器(trap)。

所有的捕捉器是可选的。如果没有定义某个捕捉器,那么就会保留源对象的默认行为。

handler.getPrototypeOf()
handler.setPrototypeOf()
handler.isExtensible()
handler.preventExtensions()
handler.getOwnPropertyDescriptor()
handler.defineProperty()
handler.has()//in 操作符的捕捉器。
handler.get(target, property)
handler.set(target, property, value)
handler.deleteProperty()//delete 操作符的捕捉器。
handler.ownKeys()
handler.apply()
handler.construct()//new 操作符的捕捉器。

Proxy对象和原始对象

let target = {};
let p = new Proxy(target, {});

p.a = 37;   // 操作转发到目标

console.log(target.a);    // 37. 操作已经被正确地转发

target.a=4;
console.log(p.a)//4

console.log(target==p)//false

总结
        1. Proxy使用上比Object.defineProperty方便的多。
        2. Proxy代理整个对象,Object.defineProperty只代理对象上的某个属性。
        3. vue中,Proxy在调用时递归,Object.defineProperty在一开始就全部递归,Proxy性能优于Object.defineProperty。
        4. 对象上定义新属性时,Proxy可以监听到,Object.defineProperty监听不到。
        5. 数组新增删除修改时,Proxy可以监听到,Object.defineProperty监听不到。
        6. Proxy不兼容IE,Object.defineProperty不兼容IE8及以下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值