【前端知识】JavaScript——属性及属性的特性

本文介绍了JavaScript中的数据属性和访问器属性,包括它们的四个基本特性[[Configurable]]、[[Enumerable]]、[[Writable]]和[[Value]]。通过Object.defineProperty()方法可以修改属性的特性,例如使属性变得不可修改或不可配置。此外,文章还讨论了如何定义多个属性以及如何读取属性的特性,提到了Object.defineProperties()和Object.getOwnPropertyDescriptors()方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【前端知识】JavaScript——属性及属性的特性

一、数据属性

数据属性包含一个保存数据值的位置。值会从这个位置读取,也会写入到这个位置。

数据属性的四个特性:

特性描述
[[Configurable]]表示属性是否可以通过 delete 删除并重新定义,是否可以修改它的特性,以及是否可以把它改为访问器属性。
[[Enumerable]]表示属性是否可以通过 for-in 循环返回。
[[Writable]]表示属性的值是否可以被修改。
[[Value]]包含属性实际的值
// 当我们创建一个对象时,name的值会被设置到 [[Value]]特性中,[[Configurable]]、[[Enumerable]]和[[Writable]] 都会被设置为 true
let person = { 
 name: "Outman" 
};

如果要修改特性的默认值,可以使用 Object.defineProperty() 方法:

  1. 修改 writable 特性
let person = {}; 
Object.defineProperty(person, "name", { 
 writable: false, // 表示不可修改
 value: "Outman" 
}); 
console.log(person.name); // "Outman" 
person.name = "manOut";  // 尝试修改name属性
console.log(person.name); // "Outman",无法修改name值,因为 writable 为 false
  1. 修改 configurable 特性
let person = {}; 
Object.defineProperty(person, "name", { 
 configurable: false, // 表示不可配置
 value: "Outman" 
}); 
console.log(person.name); // "Outman" 
delete person.name; // 尝试 delete name属性
console.log(person.name); // "Outman",无法delete name属性,因为 configurable 为 false

// 另外,值得一提的是,一个属性被定义为不可配置之后,将无法再变回可配置的!

二、访问器属性

包含一个获取(getter)函数和一个设置(setter)函数,不过这两个函数不是必需的。

特性描述
[[Configurable]]表示属性是否可以通过 delete 删除并重新定义,是否可以修改它的特性,以及是否可以把它改为数据属性。
[[Enumerable]]表示属性是否可以通过 for-in 循环返回。
[[Get]]获取函数,在读取属性时调用。
[[Set]]设置函数,在写入属性时调用。

访问器属性的特性也是通过 Object.defineProperty() 进行修改:

// 定义一个对象,包含伪私有成员 year_和公共成员 edition 
let book = { 
    year_: 2017, 
    edition: 1
}; 
Object.defineProperty(book, "year", { 
    get() { 
        return this.year_; 
    }, 
    set(newValue) { 
        if (newValue > 2017) { 
            this.year_ = newValue; 
            this.edition += newValue - 2017; 
        } 
    } 
}); 
book.year = 2018; 
console.log(book.edition); // 2

三、定义多个属性

若要定义多个属性,可以使用 Object.defineProperties() 方法实现:

let book = {}; 
Object.defineProperties(book, { 
    year_: { 
        value: 2017 
    }, 
    edition: { 
        value: 1 
    }, 
    year: { 
        get() { 
            return this.year_; 
        },
        set(newValue) { 
            if (newValue > 2017) { 
                this.year_ = newValue; 
                this.edition += newValue - 2017; 
            } 
        } 
    } 
});

四、读取属性的特性

若要读取属性的特性,可以使用 Object.getOwnPropertyDescriptor() 方法实现;若要读取属性的多个特性,可以使用ECMAScript 2017 新增得 Object.getOwnPropertyDescriptors() 静态方法。这个方法会在每个自有属性上调用Object.getOwnPropertyDescriptor()并在一个新对象中返回它们。

let descriptor = Object.getOwnPropertyDescriptor(book, "year_"); 
console.log(descriptor.value); // 2017 
console.log(descriptor.configurable); // false 
console.log(typeof descriptor.get); // "undefined" 
let descriptor = Object.getOwnPropertyDescriptor(book, "year"); 
console.log(descriptor.value); // undefined 
console.log(descriptor.enumerable); // false 
console.log(typeof descriptor.get); // "function"

console.log(Object.getOwnPropertyDescriptors(book)); 
// { 
// edition: { 
// configurable: false, 
// enumerable: false, 
// value: 1, 
// writable: false 
// }, 
// year: { 
// configurable: false, 
// enumerable: false, 
// get: f(), 
// set: f(newValue), 
// }, 
// year_: { 
// configurable: false, 
// enumerable: false, 
// value: 2017, 
// writable: false 
// } 
// }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端Outman

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值