JavaScript之Object.defineProperty

118 阅读2分钟

前情提要

在vue2的方法中,对于对象和数组的修改

  • 对象:

通过 this.对象.属性 = xxx 是不能实现页面响应的,但是数据确实修改了。

可以通过this.$set(修改的对象,修改的属性,改为什么值) 修改对象的某个属性值,

通过 this.$delete(删除的对象,删除的属性)来删除对象中某个属性

  • 数组:

通过 this.数组[下标] = xxx 是不能实现页面响应的,但是数据确实修改了。

可以通过 this.$set(修改的数组, 下标, 修改的值) 来修改数组中某个下标所在元素的值,

通过 数组.splice(开始的索引, 替换的数量, 替换的内容) 可以把数组某个位置之后的值都替换为某个值


Object.defineProperty 方法

Object.defineProperty:vue 的数据代理,数据劫持,计算属性的底层都是这个方法。

		let person = {
            name:'哈喽喔',
            sex:'male'
        }
        Object.defineProperty(person,'age',{
            value:22
        })
        console.log(person);
        
        // 遍历对象方式一 for  in
         for (const key in person) {
            console.log(key,':',person[key]);
         }

		//遍历对象方式二  keys方法
        console.log(Object.keys(person));

其中 Object.defineProperty(person, 'age' ,{ value:29 }) 就是把age属性加到person对象中,age的属性值为29

Object.keys(person)
就是将person对象中存在的 属性名 放到数组中,函数返回这个数组

最后遍历这个对象

结果:

在这里插入图片描述 可见遍历person时没有打印出age,所以 通过defineProperty加入到对象中的属性默认是不会被遍历出来的(不可遍历

enumerable

只需要在defineProperty方法的最后一个参数的对象中加入属性,enumerable: true 即可遍历加入的属性,

        Object.defineProperty(person,'age',{
            value:22,
 			enumerable: true	//控制属性是否可以被枚举,默认值 false
        })

writable

通过writable: true 控制属性可以被修改

        Object.defineProperty(person,'age',{
            value:22,
 			writable: true	//控制属性是否可以被修改,默认值 false
        })

configurable

通过configurable: true 控制属性可以被删除

        Object.defineProperty(person,'age',{
            value:22,
 			configurable: true	//控制属性是否可以被删除,默认值 false
        })

get() 和 set()

	let number = 22		// 数据代理
        let person = {
            name:'哈喽喔',
            sex:'male'
        }
        Object.defineProperty(person,'age',{
            // value:22
            get(){
                console.log('有人读取了age属性');
                return number
            },
            set(value){
                console.log('有人修改了age属性,且值为'+value);
                number = value
            }
        })
        console.log(person);

打印person对象可见

在这里插入图片描述

鼠标悬停在三个小点上时候,提示invoke property getter 即调用属性getter方法,点击时执行上面defineProperty中的get()

点击之后,调用执行defineProperty中配好的get()方法,得到number对应值 在这里插入图片描述

通过控制台修改age的值之后再次获取,调用执行get()方法可以看到,值被修改了↓

在这里插入图片描述

这样就实现了数据代理。