JavaScript对象属性修饰符:控制属性的行为和可访问性
JavaScript是一门强大而灵活的编程语言,它提供了多种方法来定义和操作对象的属性。其中一个重要的概念是属性修饰符,它们允许我们控制属性的行为和可访问性。
基本属性修饰符
JavaScript中的属性修饰符主要包括writable
、enumerable
和configurable
。我们可以使用Object.defineProperty
方法来设置这些属性。
writable(可写性)
writable
属性决定了属性是否可以被重新赋值。当设置为false
时,属性不可被重新赋值,否则可以。
ini
var obj = {
b: 2,
};
Object.defineProperty(obj, 'a', {
value: 10,
writable: false, // 不可重写
});
obj.a = 'abc'; // 这里会抛出错误,因为属性a不可重写
console.log(obj.a); // 输出仍然是10
enumerable(可枚举性)
enumerable
属性决定了属性是否会出现在for...in
循环中或通过Object.keys
方法获取。当设置为false
时,属性不可被遍历,否则可以。
javascript
var obj = {
b: 2,
};
Object.defineProperty(obj, 'a', {
value: 10,
enumerable: false, // 不可遍历
});
for (var key in obj) {
console.log(key); // 这里不会输出属性a
}
var keys = Object.keys(obj);
console.log(keys); // 这里不会包含属性a
configurable(可配置性)
configurable
属性决定了属性是否可以被删除或属性描述符是否可以被修改。当设置为false
时,属性不可被删除或修改属性描述符,否则可以。
javascript
var obj = {
b: 2,
};
Object.defineProperty(obj, 'a', {
value: 10,
configurable: false, // 不可修改描述符本身
});
// 下面的代码会抛出错误,因为属性a不可被删除
delete obj.a;
Object.defineProperty(obj, 'a', {
writable: true, // 这里会抛出错误,因为属性a不可被修改
});
obj.a = 'abc'; // 这里会抛出错误,因为属性a不可重写
使用getter和setter
除了基本的属性修饰符,JavaScript还允许我们使用getter和setter来定义属性的访问和赋值行为。这对于在访问或修改属性时执行特定操作非常有用。
javascript
var obj = {};
Object.defineProperty(obj, 'a', {
get: function () {
return 123; // 获取属性a时总是返回123
},
set: function (val) {
throw new Error(
`属性a不能被重新赋值,你尝试赋值为${val}`
);
},
});
console.log(obj.a); // 输出123
obj.a = 'abx'; // 这里会抛出错误,因为属性a不可重写
在上面的示例中,我们使用getter来获取属性a的值,并使用setter来阻止对属性a的重新赋值。这允许我们在属性访问和赋值时执行自定义逻辑。
在class类中的使用
在ES6类(Class)的构造函数中定义属性的getter和setter方法,可以直接在构造函数中使用Object.defineProperty
javascript
class MyClass {
constructor() {
this._a = 123;
Object.defineProperty(this, 'a', {
get: function () {
return this._a;
},
set: function (val) {
throw new Error(`属性a不能被重新赋值,你尝试赋值为${val}`);
},
});
}
}
const instance = new MyClass();
console.log(instance.a); // 输出123
instance.a = 456; // 这里会抛出错误,因为属性a不可重写
当使用ES6类(Class)来定义对象时,可以更简洁地定义属性的getter和setter方法,而不需要使用Object.defineProperty
。ES6引入了一种更友好的语法,可以在类中使用get
和set
关键字来创建属性的getter和setter。
javascript
class MyClass {
constructor() {
this._a = 123;
}
get a() {
return this._a; // 这是属性a的getter方法
}
set a(val) {
throw new Error(
`属性a不能被重新赋值,你尝试赋值为${val}`
);
}
}
结合遇到的面试题
- js怎么观察对象是否被调用呢?
- 获取对象属性在什么情况下会报错?
- 手写一个ObjectFreeze