【前端知识】JavaScript——属性及属性的特性
一、数据属性
数据属性包含一个保存数据值的位置。值会从这个位置读取,也会写入到这个位置。
数据属性的四个特性:
特性 | 描述 |
---|---|
[[Configurable]] | 表示属性是否可以通过 delete 删除并重新定义,是否可以修改它的特性,以及是否可以把它改为访问器属性。 |
[[Enumerable]] | 表示属性是否可以通过 for-in 循环返回。 |
[[Writable]] | 表示属性的值是否可以被修改。 |
[[Value]] | 包含属性实际的值 |
// 当我们创建一个对象时,name的值会被设置到 [[Value]]特性中,[[Configurable]]、[[Enumerable]]和[[Writable]] 都会被设置为 true
let person = {
name: "Outman"
};
如果要修改特性的默认值,可以使用 Object.defineProperty() 方法:
- 修改 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
- 修改 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
// }
// }