Object.defineProperty详解!为什么会被vue3被抛弃?

简介: 【10月更文挑战第4天】Object.defineProperty详解!为什么会被vue3被抛弃?

vue中的defineProperty简介

在 Vue.js 中,Object.defineProperty 是一个非常重要的工具,特别是在 Vue 2.x 的响应式系统中。Vue 2.x 使用 Object.defineProperty 来劫持对象属性的 getter 和 setter,从而能够在数据变动时做出响应。

defineProperty的作用

静态方法Object.defineProperty() 直接在对象上定义新属性,或修改对象上现有的属性,并返回该对象。

语法:

Object.defineProperty(obj, prop, descriptor)

参数

默认值/子属性 默认值 含义
obj 要在其上定义属性的对象。 Object
prop 要定义或修改的属性的名称或名称。 sting
descriptor 正在定义或修改的属性的描述符。Object configurable false 是否可以删除或编辑
enumerable false 能否枚举
value undefined**
writable false 能否修改
get
set

创建一个对象obj,并定义一些值。再创建一个空对象target

var obj = {
   
        count : 0,
        list : [1,2,4]
}
var target = {
   };

它主要有以下几个功能:

功能一:通过value设置属性值

由于Object.defineProperty可以给对象定义属性,我们通过value,可以动态地将obj对象的属性动态地添加给target中。

for (let key in obj){
   
        Object.defineProperty(target,key,{
   
                value: obj[key]
        })
}
console.log(target);

输出结果:
成功获取到了obj中的属性值

功能二:通过writable设置是否可写/修改

1.当writable的值为false时

尝试将count的值从0改为10

for (let key in obj){
   
    Object.defineProperty(target,key,{
   
            value: obj[key],
            writable: false
    })
}
target.count = 10;//将count中的值0修改成10
console.log(target.count);  //0  当writable为false时,无法改变count的值

当writable为false时,无法改变count的值

2.当writable的值为true时
尝试将count的值从0改为10

    for (let key in obj){
   
            Object.defineProperty(target,key,{
   
                value: obj[key],
                writable: true
            })
        }
        target.count = 10;//将count中的值0修改成10
        console.log(target.count);  //10

功能三:通过enumerable设置属性值是否允许遍历

在上面的代码基础上,我们添加enumerable属性并尝试遍历target中的属性值

1.当enumerable的值为false时

       for (let key in obj){
   
            Object.defineProperty(target,key,{
   
                value: obj[key],
                writable:true,
                enumerable: false
            })
        }
        for (key in target){
   
                console.log(key);//遍历target中的属性值并打印,此时结果为空
        }

2.当enumerable的值为true时

   for (let key in obj){
   
            Object.defineProperty(target,key,{
   
                value: obj[key],
                writable:true,
                enumerable: ture
            })
        }
        for (key in target){
   
                console.log(key);//遍历target中的属性值并打印,此时结果为空
        }

输出结果:
成功遍历对象并打印出结果

功能四:通过configurable设置属性是否可删

在上面的代码基础上,我们添加configurable属性并尝试用delete方法删除target中的属性

1.当configurable的值为false时

for (let key in obj){
   
        Object.defineProperty(target,key,{
   
                value: obj[key],
                writable:true,
                enumerable: false,
                configurable: false
        })
}
delete target.count;//删除count属性
console.log(target);

输出结果:
由于此方法为fasle时,属性值无法删除,target中仍有count属性

2.当configurable的值为true时

 for (let key in obj){
   
            Object.defineProperty(target,key,{
   
                value: obj[key],
                writable:true,
                enumerable: false,
                configurable: true
            })
        }
delete target.count;//删除count属性

功能五:通过get方法获取属性的值

【注意!】当设置get方法时,不能有value和writable方法,否则会报错
get方法的值是一个函数,此函数不需要参数

 for (let key in obj){
   
    Object.defineProperty(target,key,{
   
            //value: obj[key],
            //writable:true,
            enumerable: false,
            configurable: true,
            get: function(){
   
                    return obj[key]
            }
    })
}
console.log(target.count);

输出结果:
成功获取到了指定属性(count)的值

功能六:通过set方法设置属性的值

set方法的值也是一个函数,定义时会自动注入一个参数,此参数会设置属性的值

for (let key in obj){
   
    Object.defineProperty(target,key,{
   
        //value: obj[key],
        //writable:true,
        enumerable: false,
        configurable: true,
        get: function(){
   
                return obj[key]
        }set: function(val){
   
                console.log(val);//打印设置好的值
            }
    })
}
target.count = 10;//修改count属性的值为10

输出结果:
成功修改了指定属性(count)的值

【注意】set方法只有在设置/修改指定属性值的时候,才会触发,即调用set下的匿名函数

vue2为什么使用Object.defineProperty

通过上述Object.defineProperty的使用介绍,我们可以知道,Vue 2.x 的响应式系统选择使用 Object.defineProperty ,主要是基于以下原因:

  1. 兼容性Object.defineProperty 是 ECMAScript 5.1 标准的一部分,因此在 Vue 2.x 发布时,它具有很好的浏览器兼容性。这使得 Vue 能够在多种浏览器环境中运行,而无需使用额外的转换工具或库。
  2. 实现简单:使用 Object.defineProperty 可以直接在一个对象上定义新属性,或者修改一个对象的现有属性,并为其添加 getter 和 setter。这使得 Vue 可以轻松地拦截属性的访问和修改,从而实现数据的响应式更新。
  3. 性能考虑:虽然 Object.defineProperty 在某些情况下可能不是最优的选择(例如,当需要频繁添加或删除属性时),但在 Vue 的应用场景中,它通常能够提供足够的性能。Vue 主要用于构建用户界面,而不是进行大量的数据操作,因此 Object.defineProperty 的性能限制在 Vue 的上下文中通常是可以接受的。
  4. 与 Vue 的设计目标相契合:Vue 的设计目标之一是使开发者能够轻松地构建用户界面,而无需深入了解底层技术细节。使用 Object.defineProperty 可以帮助 Vue 隐藏这些底层细节,使开发者能够更专注于构建用户界面。

为什么Vue3废弃了Object.defineProperty

Vue3废弃Object.defineProperty,一部分原因就是因为其有其局限性。

例如,它不能检测对象属性的添加或删除,也不能很好地处理数组索引和长度的变化。

为了解决这些问题,Vue 提供了一些额外的工具和方法(如 Vue.setVue.delete 和一些特殊的数组方法),但这些方法需要开发者显式地调用。

因此,在 Vue3.x 中,响应式系统得到了改进,使用了 Proxy 而不是 Object.defineProperty

Proxy 可以提供更全面和灵活的数据劫持能力,能够检测更多的数据变动情况,包括对象属性的添加和删除以及数组索引和长度的变化。这使得 Vue 3.x 的响应式系统更加强大和易用。

相关文章
|
1月前
|
JavaScript
vue学习(7)Object.defineProperty
vue学习(7)Object.defineProperty
32 2
|
2天前
|
JavaScript
Vue 的响应式原理中 Object.defineProperty 有什么缺陷
Vue 的响应式原理主要依赖于 `Object.defineProperty`,但该方法存在一些缺陷:无法检测到对象属性的添加和删除,且对大量数据进行代理时性能较差。Vue 3 中改用了 Proxy 来解决这些问题。
|
2天前
|
JavaScript 前端开发 UED
为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty
Vue 3.0 采用 Proxy 替代 Object.defineProperty,主要因为 Proxy 提供了更全面、高效的数据拦截能力,支持对更多操作进行拦截和自定义处理,同时减少了对对象的限制,提升了框架性能和开发体验。
|
5月前
|
JavaScript
Vue : Object.defineProperty()
Vue : Object.defineProperty()
40 2
|
5月前
|
JavaScript
JS之Object.defineProperty方法
JS之Object.defineProperty方法
|
5月前
|
JavaScript 数据安全/隐私保护 开发者
常见的vue面试中的proxy和object.defineProperty的区别
常见的vue面试中的proxy和object.defineProperty的区别
|
10月前
【Vue2.0学习】—Object.defineProperty(三十)
【Vue2.0学习】—Object.defineProperty(三十)
|
5月前
|
监控 JavaScript 前端开发
【面试题】vue2双向绑定原理:深入响应式原理defineProperty、watcher、get、set
【面试题】vue2双向绑定原理:深入响应式原理defineProperty、watcher、get、set
|
监控 JavaScript 索引
深入理解vue2.x中Object.defineproperty()和vue3.x中Proxy
深入理解vue2.x中Object.defineproperty()和vue3.x中Proxy
195 0
深入理解vue2.x中Object.defineproperty()和vue3.x中Proxy
|
JavaScript 前端开发 API
Vue数据监听Object.definedProperty()方法的实现
Vue数据监听Object.definedProperty()方法的实现