JS中的对象属性修饰符(Object.defineProperty)

引言

如果我们希望对JS中的一个属性进行比较精确的操作控制就需要使用到属性描述符,通过属性描述符可以精确的添加或者修改对象的属性。属性描述符需要使用 Object.defineProperty 来对属性进行添加或者修改。

Object.defineProperty

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

它可以接受三个参数

  • 参数一:要定义属性的对象
  • 参数二:要定义或修改的属性的名称或 Symbol;
  • 参数三:要定义或修改的属性描述符

它的返回值

  • 被传递给函数的对象

属性描述符分类

属性描述符分为数据属性以及存取属性。

image.png

数据描述符

数据描述符不可以有getset

configurable

表示属性是否可以通过delete删除属性,是否可以修改它的特性,或者是否可以将它修改为存取属性 描述符。

也就是说将该属性设置为false,则表明该属性不可删除,也不可能去再次配置

不可删除案例

var obj = {
    name : 'why',
    age:18
}

Object.defineProperty(obj,"address",{
    //很多配置
    value:'北京',
    configurable:false  //该属性不可删除(还不可以去再次配置)
})

delete obj.address  
console.log(obj.address);   //输出北京

不可再次配置案例

var obj = {
    name : 'why',
    age:18
}

Object.defineProperty(obj,"address",{
    value:'北京',
    configurable:false  //该属性不可删除(还不可以去再次配置)
})

Object.defineProperty(obj,"address",{
    value:'南京',
    configurable:true 
})

console.log(obj.address);   //报错

Enumerable

表示属性是否可以通过for-in或者Object.keys()返回该属性。也就是说表明该属性是否可被枚举

不可枚举案例

var obj = {
    name : 'why',
    age:18
}

Object.defineProperty(obj,"address",{
    value:'北京',
    configurable:false,
    enumerable:false,
})


console.log(obj); //没有北京
for(let value in obj){
    console.log(value); //打印不了北京
}

writable

表示该属性是否可以被赋值(修改,写入)。

var obj = {
    name : 'why',
    age:18
}

Object.defineProperty(obj,"address",{
    value:'北京',
    configurable:false,
    enumerable:false,
    writable:false, //表示该属性是否可以被赋值(修改,写入)
})

obj.address = '上海'

console.log(obj.address);  //还是北京
for(let value in obj){
    console.log(value);  //还是北京
}

数据描述符的默认值

var obj = {
    name : 'why',
    age:18
}

Object.defineProperty(obj,"address",{
    value:'北京',
    //假如不写 下面三个参数的默认值都是false
    // configurable:false,
    // enumerable:false,
    // writable:false, 
})

obj.address = '上海'
console.log(obj.address); //北京
delete obj.address 
console.log(obj.address); //北京并没被删除
for(let value in obj){
    console.log(value);  //北京没有被打印出来
}

不使用属性修饰符的默认值

var obj = {
    name : 'why',
    age:18
}
obj.address = '上海'
// 下面三个参数都是true
// configurable:true,
// enumerable:true,
// writable:true, 

存取属性描述符

属性描述符不可以有value以及writable

什么时候用到呢?

  • 隐藏真实属性,不希望被外界赋值与使用。
  • 截获某一个属性它访问和设置值的过程。
var obj = {
    name : 'why',
    age:18,
    _address:'北京'  //隐藏真实属性
}

//什么时候用到呢
Object.defineProperty(obj,'address',{
    //不可以有value
    enumerable:true,
    configurable:true,
    get(){
        foo()
        return this._address
    },
    set(value){
        bar()
        this._address = value
    },
})
obj.address = '上海'
console.log(obj.address);

function foo(){
    console.log('获取一次address的值');
}

function bar(){
    console.log('设置了一次address的值');
}

vue2响应式原理也是用到了存储属性修饰符。关于对源码的理解我也会在后续博文中更新。

转自本人掘金 https://juejin.cn/post/7106826860964626468/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值