重新阅读Object.defineProperty属性

201 阅读2分钟

一、介绍

Object.defineProperty() 在vue3以前的版本用于数据的双向绑定。

参数:

  • obj: 定于属性的对象

  • prop: 定义或修改的属性的名称或 Symbol 。

  • descriptor: 要定义或修改的属性描述符。 descriptor的属性

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

  • writable:当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符 (en-US)改变。默认为 false

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

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

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

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

二、例子

writable属性:

常规使用

const obj = {}
Object.defineProperty(obj, 'name', {
})

obj.name = 'name'
console.log(obj)

这里修改了obj对象下的name值,但是输出中并未显示,nameundefined

如图

image.png

这里开始改变它的值

const obj = {}
Object.defineProperty(obj, 'name', {
  writable: true
})

obj.name = '积雷山摩云洞'
console.log(obj)

image.png

set与get

修改obj的属性,为obj添加一个name

const obj = {}
let name = null
Object.defineProperty(obj, 'name', {
  set: function(newVal) {
    console.log('set '+newVal)
    name = newVal
    // return oldVal = newVal
  },
  get: function() {
    console.log('get '+ name)
    return name
  }
})

obj.name
obj.name = '积雷山摩云洞1'
console.log(obj)

可以看到obj.name 触发了get事件, 而重新设置属性,则触发了set属性

image.png

这里有个过程,第一次obj.name时触发了get,第二次赋值时触发了set,这时执行了console输出,当点击name之后,再次触发了get属性

数据劫持的流程

image.png 未完待续!!!