object.defineproperty()

人气:408 ℃/2022-12-26 10:10:59

object.defineproperty()是什么呢?不知道的小伙伴来看看小编今天的分享吧!

一、Object.defineProperty()的定义:

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

二、和.操作符或者[]操作符的区别:

Object.defineProperty()能够更深入地定义一个对象,它操作的不仅仅是属性的值,也可以修改属性的一些特性,比如是否可修改,是否可遍历,当然值也是属性其中的特性之一。

三、Object.defineProperty(obj, prop, descriptor)接受3个参数:

obj: 要操作的对象

prop: 要操作的属性

descriptor: 描述符对象。包含6个属性:configurable、enumerable、writable、value、get、set

注意:

应当直接在Object构造器对象上调用此方法,而不是在任意一个Object类型的实例上调用。

四、属性类型:

1、数据属性

数据属性包含一个数据值的位置。在这个位置可以读取和写入值

数据属性有4个描述其行为的特性:

configurable: 能否通过delete删除属性,能否修改属性特性(注意是特性),能否修改为访问器属性,默认是true

enumerable: 能否通过for-in遍历到该属性,默认是true

writable: 能否修改属性值,默认是true

value: 这个属性的数据值。读取属性值的时候,从这里读取;写入属性值得时候,把新值保存在这个位置。默认是undefined

例如:

let person = {}

person.name // 给person添加一个数据属性,Configurable、Enumerable、Writable默认是true,Value是undefinedperson.name = 'a' // Value特性被设置为'a'

如果将configurable设置为false 那么除了value和writable之外的特性都不能被修改(本身也不能再改为true了),如果修改会被忽略,严格模式会报错。

在configurable为false的情况下,writable为true可修改为false,如果writable为false,修改为true也会被忽略,严格模式报错。

Object.defineProperty(person, 'name', { configurable: false})Object.defineProperty(person, 'name', { value: 'b'})console.log(person.name) // b configurable为false,writable为true时还能修改Object.defineProperty(person, 'name', { writable: false})

person.name = 'c' // errorObject.defineProperty(person, 'name', { writable: true}) // error

2、访问器属性

访问器属性不包含数据值,包含一对getter和setter函数(不需要同时存在)。

访问器属性必须通过Object.defineProperty定义。访问器属性有以下四个特性:

configurable: 能否通过delete删除属性,能否修改属性特性(注意是特性),能否修改为数据属性,默认是true

enumerable: 能否通过for-in遍历到该属性,默认是true

get: 在读取属性时调用的函数。默认值是undefined

set: 在写入属性时调用的函数。默认是undefined

五、数据属性和访问器属性相互转换:

数据属性 -> 访问器属性

给数据属性设置了get或set特性,value和writable特性就会被废弃,该属性变为访问器属性

访问器属性 -> 数据属性

给访问器属性设置了value或writable特性,get和set特性就会被废弃,该属性变为数据属性

注意:只有在configurable为true的情况下才可以相互转换,即使数据属性中在configurable为false的情况可以修改value或writable,访问器属性转数据属性只设置value或writable也不行。

以上就是小编今天的分享了,希望可以帮助到大家。

object.defineproperty()缺点

Proxy对象代理api简单入门

前沿

Vue2实现响应式是利用了Object.defineProperty(),而到Vue3的时候实现响应式确改成了Proxy

Vue为什么要这样做?

主要在于Object.defineProperty()存在一些无法修复的缺陷

1、无法检测到对象的新增和删除

<div>{{userInfo}}</div>data (){ return { userInfo:{ name:'xxx' } }}, created () { this.userInfo.age = 222}// userInfo显示结果// userInfo:{ "name": 'xxx' }

2、无法监听数组变化

<div>{{arr}}</div>data (){ return { arr:[1,2] } }}, created () { this.arr[0]=3}// arr显示结果// arr:[1,2]

要解决的话,需要通过vue2的$set方法,比如

this.$set(this.userInfo,'age',222)this.$set(this.arr,0,3)

但是proxy就能很好地解决这些问题

Proxy简介

Proxy是对象的一个代理,可以实现基本操作的拦截和自定义

// target是要代理的对象// handle是一个容纳一批特定属性的占位符对象const p = new Proxy(target, handler)

看起来是不是有点懵,下面我们通过这个例子来入个门

const target={ a:1}const handler={ // get拦截 // 在这里可以做一些日志处理 // target代理的对象 // key为对象的属性 // 例如:p.a,那么target就是p,key就是a get(target,key){ console.log(key '被获取了') if(key in target){ return target[key] }else{ return '我不知道' } }, // set拦截 // 在这里可以做一些日志处理 // target代理的对象 // key为对象的属性 // value是设置的值 // 例如:p.a=3,那么target就是p,key就是a,value就是3 set(target,key,value){ if(key in target){ console.log(`属性${key}被设置了新的值${value}`) }else{ console.log(`添加了新的属性${key},值为${value}`) } target[key]=value return true }, // delete拦截 // 在这里可以做一些日志处理 // target代理的对象 // key为对象的属性 // 例如:delete p.a,那么target就是p,key就是a deleteProperty(target,key){ if(key in target){ console.log(`属性${key}被删除了`) } delete target[key] }}

我们做一下简单的测试

const p = new Proxy(target, handler)p.a // 输出1p.b // 输出我不知道p.a=3 // 输出属性a被设置了新的值3p.b=6 // 输出添加了新的属性b,值为6delete p.a // 输出属性a被删除了delete p.b // 没有任何输出

好了Proxy的入门就讲到这了

觉得效果不错的请帮忙加个关注点个赞,经常分享前端实用开发技巧

推荐

首页/电脑版/网名
© 2026 NiBaKu.Com All Rights Reserved.