详细分析Object.defineProperty()

一、理解Object.defineProperty()

Vue中的在其他位置(非data函数内) 比如methods使用Object.defineProperty() 创建对象 并不是响应式的,这是因为在渲染挂载阶段,每个data函数中的对象都创建了dep实例对象,当data函数中的数据发生变化时,就会通知watcher执行notify函数进行数据的重新渲染,而在其他位置并不会创建dep实例对象,所以就有了$set解决这一问题

Object.defineProperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性

Object.defineProperty(obj, prop, desc)

obj:需要定义属性的当前对象

prop:当前需要定义的属性名

desc:属性描述符

一般通过为对象的属性赋值的情况下,对象的属性可以修改也可以删除,但是通过Object.definePeoperty()定义属性,通过描述符的设置可以进行更精确的控制对象属性

通过Object.defineProperty()为对象定义属性,有两种形式,且不能混合使用,分别为数据描述符、存取描述符

1、数据描述符 --特有的两个属性(value、writable)

注意:当使用了writable和value属性,不允许使用getter或setter这两个方法

  • writable: 描述对象是否可写(是否只读)

    • 当我们之间在一个对象上定义某个属性时, writable默认为true

    • 当我们通过属性描述符定义一个属性时, writable默认为false

 let Person = {};
  Object.defineProperty(Person, "name", {
    value: "QQ",
    // writable默认值是false, 不能改变属性的值
  });
  Person.name = "qq";
  console.log(Person.name); // QQ
​
​
​
​
  let Person = {};
  Object.defineProperty(Person, "name", {
    value: "QQ",
    writable: true, // 可以改变value值
  });
  Person.name = "qq";
  console.log(Person.name); // qq

2、存储描述符 --是由一对 getter、setter函数功能来描述的属性

注意:当使用了getter或setter方法,不允许使用writable和value这两个属性

get:一个给属性提供getter的方法,如果没有getter则为undefined。该方法返回值被用作属性值。默认为undefinedset:一个给属性提供setter的方法,如果没有setter则为undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认值为undefined

getter/setter:

当设置或获取对象的某个属性的值的时候,可以提供getter/setter方法。

  • getter 是一种获得属性值的方法

  • setter是一种设置属性值的方法。

在特性中使用get/set属性来定义对应的方法。

通俗的讲:在访问属性的时候会触发getter函数,在属性值被修改的时候会触发setter函数

   var obj = {
        a: 1
    }
    let v = obj.a
    Object.defineProperty(obj, 'a', {
        get() {
            console.log("读取")
            return v
        },
        set(val) {
            console.log("修改")
            v = val
        }
    })
    obj.a = 9 //修改
    obj.a //读取

注意:get或set不是必须成对出现,任写其一就可以。如果不设置方法,则get和set的默认值为undefined。一般情况下都成对出现的,缺少get获取不到属性值,缺少set可以修改,只是不是通过Object.defineProperty的方式进行修改

当使用存取器描述属性的特性的时候,允许设置一下特性属性:

var obj = {};
  Object.defineProperty(obj, "newKey", {
    get: function () {} | undefined,
    set: function (value) {} | undefined,
    configurable: true | false,
    enumerable: true | false,
  });

数据描述符和存取描述均具有以下描述符:

configrable 描述属性是否配置,以及可否可以通过delete删除(是否可配置)

  • 当我们之间在一个对象上定义某个属性时, configrable默认为true

  • 当我们通过属性描述符定义一个属性时, configrable默认为false

enumerable 描述属性是否会出现在for in 或者 Object.keys()的遍历中(是否枚举)

  • 当我们之间在一个对象上定义某个属性时, enumerable默认为true

  • 当我们通过属性描述符定义一个属性时, enumerable默认为false

附:

Object.defineProperty()和proxy()最大的区别就是前者监听的是属性而且不可监听变化,而后者监听的是对象而且可以监听变化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值