【小滴课堂】vue的响应式原理——Object.defineProperty

104 阅读3分钟

今天我们来聊一下Vue2底层的一些知识,我们都知道Vue的数据响应式是基于Object.defineProperty这个方法的,但是我们对于这个方法真正知道多少?

假设我们有一个对象,目前我们只知道以下这些

const girlfriend = {
            name:"小红",
            sex:'女'
      }

然后我们后面越交流就发现越多,我们就想把这些信息加进去,然后这个对象我们一开始就定义好了,也不能用最原始的方式重新认识并加进去吧。然后我们就可以通过 Object.defineProperty() 这个方法添加进去

Object.defineProperty()会接收三个参数,第一个参数是对象名,第二个参数是对象的属性,第三个是属性的相关操作包括属性值。

Object.defineProperty(girlfriend,'age',{
            value:18
        })

通过传入年龄,然后我们可以通过控制台打印这个值

我们得到这些信息,但是发现这个加进来的age属性颜色跟其他不一样,这是为什么呢?因为他是一个不可枚举的,什么是不可枚举呢?就是说这不能修改,也不能遍历出来.

\

\

但是有的人问为什么不一开始就加进去呢?因为我们想做到那种数据响应式,vue2 就是通过Object.defineProperty来实现数据响应式。

然后我们为了能让他具有可枚举性,我们可以给这个属性添加一个配置项

Object.defineProperty(girlfriend,'age',{
            value:18,
            enumerable:true
       })

enumerable是控制这个属性是否可枚举。默认为false

我们来看浏览器

这样我们就做到了可枚举,但是还不能修改这个值,我们再添加一个配置项 writable,他是控制这个属性值是否可以修改。默认为false

   Object.defineProperty(girlfriend,'age',{
            value:18,
            enumerable:true,
            writable:true
        })

我们看浏览器

这样我们就修改到了,然后我们又想玩意以后想删除它呢?我们可以再加一个配置项configurable,就是控制属性是否可以删除,默认为false

        Object.defineProperty(girlfriend,'age',{
            value:18,
            enumerable:true,
            writable:true,
            configurable:true
        })

我们来看浏览器

这样我们就做到了删除了。

但是这个方法的优点还不止这些,我们还有一个getter和setter,我们来看一下

let ageNumber = 20
        const girlfriend = {
            name:"小红",
            sex:'女'
        }
        Object.defineProperty(girlfriend,'age',{
            get:function(){
                return ageNumber
            }
        })

这里我们在外面声明了一个数,我们通过传入来修改,这样我们就可以使用这个getter函数了。我们看一下浏览器

上面那三个点的意思是告诉我们要去获取一下才可以获取到,所以我一点击就可以获取到了,然后我们想修改它又应该怎么做呢?我们可以通过setter去知悉

        Object.defineProperty(girlfriend,'age',{
            get:function(){
                return ageNumber
            },
            set:function(val){
                console.log('有人修改了age的值,修改后的值为:'+val);
                ageNumber=val
            }
        })

我们去看浏览器

通过上面两个配置项,我们可以知道这个这个值什么时候被修改,也可以知道什么时候被调用,这样就能让数据流向更清晰而且可以追寻。

这样我们就知道了Object.defineProperty这个方法的使用了