defineProperty介绍

本文详细介绍了Vue2中常用的Object.defineProperty方法,包括其参数、属性描述符的作用,以及get和set方法的使用。通过实例展示了如何使用该方法进行属性的增删改查操作,以及模拟实现简单的响应式数据。此外,还通过一个需求演示了get和set如何将变量与对象属性关联起来,实现数据的自动更新。
摘要由CSDN通过智能技术生成

MDN传送们

在vue2中经常会听到这个属性,我也是联系了很多遍,奈何在工作中很少能用到,所以看了忘,忘了看,索性自己写下来记录一下,方便以后随时翻阅。

Object.defineProperty(obj, prop, descriptor)

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

这是mdn的描述,嗯,看了和没看一样。来看一下它的三个参数:

  • obj 要定义属性的对象。
  • prop 要定义或修改的属性的名称或 Symbol 。
  • descriptor 要定义或修改的属性描述符。

接下来就直接通过代码来揣摩一下这个方法!
首先我们定义一个普通的对象。

let obj = {
            a: 1,
            b: 2,
            c: 3,
        }

接下来通过defineProperty给obj添加一个新的属性。

Object.defineProperty(obj, 'name', {
            value: 'yzl'
        })

控制台输出一下obj,发现被代理的属性和其他属性会有颜色的差异,被代理的属性会比较浅。
在这里插入图片描述

接下来对被代理的属性进行删,改操作并输出。

obj.name = 'sultan' // obj的name依然为yzl,因为被代理了的属性为不可变更
delete obj.name; 

输出后发现,name的值还是yzl。 说明修改和删除操作都是被了,这是因为被代理的属性默认是不可删改的,可以通过第三个参数 descriptor来控制权限。

Object.defineProperty(obj, 'age', {
            value: 12,
            writable: true, // 描述属性是否可以被修改。默认为 false。
            configurable: true, // 描述属性是否可以被删除,修改。 默认false
            enumerable: true, // 描述属性是否可以被枚举。 默认为false
        })

这里有一个enumerable, 该属性标识是否可以被枚举。 枚举的意思就是,当你通过for in循环会不会遍历到该属性

除了这些描述符,还有一对比较特殊的方法。
get和set。

Object.defineProperty(obj, 'address', {
            get() {
                return '大连'
            },
            set(value) {
                console.log(value)
            }
        })

get函数在属性被读取时候触发,set函数在属性被修改时候触发。注意get,和set不能和value或writable同时出现,否则会报错。因为value已经指定了值,get函数也是返回一个值

下面以一个需求的形式讲述get,set的用法。
现在有一个变量 pet = dag,想要给上边的obj新增一个myPet的属性,值同步变量pet的值,就可以这么写。

        let pet = 'dog';
        Object.defineProperty(obj, 'pet', {
            get() {
                return pet;
            },
            set(value) {
                pet = value;
            }
        })
        pet = 'cat';

这样的话每当你改变pet的值,obj中的myPet就会自行更新,将两个不相关的变量关联在了一起~

使用defineProperty模拟实现vue的响应式数据(一层实现)

 function mVue(option) {
            const { data } = option;
            let obj = {};
            this.observer.call(obj, data);
            this.observer(data)
            this._data = obj;
        }

        mVue.prototype.observer = function(params) {
            const keys = Object.keys(params);
            keys.forEach(key=> {
               Object.defineProperty(this, key, {
                   get: function reactiveGetter() {
                       return params[key]
                   },
                   set: function reactiveSetter(value) {
                       params[key] = value;
                   }
               })
            })
        }

        const mvm = new mVue({
            data: {
                name: 'sultan',
                address: '杭州',
                children: [
                    {
                        name: 'xiaoming',
                        age: '20',
                    },
                    {
                        name: 'xiaohong',
                        age: '18'
                    }
                ],
                obj: {
                    a: {
                        b: 1,
                    }
                }
            }
        })
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值