Object.defineProperty详解及其简单vue响应式的实现

340 阅读2分钟

image.png

😃Object.defineProperty

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

✔语法: Object.defineProperty(obj, prop, descriptor)

  • obj: 要定义属性的对象
    
  • prop: 要定义或修改的属性的名称或Symbol
    

    这里的prop是可以是已定义的,或者不存在的;如果不存在,就会被创建;如果存在则由该属性是否为configurable决定,如果是true,则可以覆盖;configurable可以防止属性被重新定义。

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

    一般都为false。

    例如enumerable,当enumerable键值为true时,你是遍历读取不了这个属性的,因为它设置了不允许迭代,同样也不会显示在对象键中;

    例如writerable,假如configurable为false,即不可重新定义,但是writerable为true,这时候你仍然能够对该属性进行赋值,但是它的值并不会真正的改变,同时也不会显式报错。

😁因为涉及到属性较多,详细可浏览MDN,这里只讲一些涉及到的重要属性:get和set,先来看看MDN里面对于这两个属性的描述:

  • get

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

  • set

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

✔总结:

  • 讲的有点抽象,大概理解它们是对象在被调用或者被修改时候触发的方法。
  • 具备覆盖性,get方法覆盖.取值行为,而set方法则覆盖赋值行为。

简单例子

impicture_20220212_142817.png

😁Vue响应式简单实现:

impicture_20220212_144141.png

缺点

  • 只能监听数组
  • 只能劫持对象的属性,显然直接监听整个对象会好很多,这样我们就不用每次劫持对象属性就要遍历整个对象。 总结:算是半成品,对于对象上新增的属性无能为力,对于数组则需要拦截它的原型方法来实现响应式。