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

【前端知识】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 
// } 
// }

猜你喜欢

转载自blog.csdn.net/weixin_42919342/article/details/131980040