0%

javascript-object-access-control

今天来看看在JavaScript中如何控制对象的可访问性。

不可扩展对象

使用Object.preventExtensions()方法可以将一个对象设置为不可扩展,不可扩展的对象不能添加新属性,但可以修改或者删除已有属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"use strict"; // eslint-disable-line

const person1 = {
name: 'zdd',
};
console.log(Object.isExtensible(person1)); // true;

Object.preventExtensions(person1);
console.log(Object.isExtensible(person1)); // false

person1.name = 'Philip'; // OK
console.log(person1.name); // Philip

delete person1.name; // OK;
console.log(person1.name); // undefined.

person1.age = 18; // Error: Cannot add property age, object is not extensible

密封对象

使用Object.seal()方法可以将一个对象密封,密封后的对象不能添加、删除属性,但可以修改属性的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
"use strict"; // eslint-disable-line

const person1 = {
name: 'zdd',
};
console.log(Object.isSealed(person1)); // false

Object.seal(person1);
console.log(Object.isSealed(person1)); // true

person1.name = 'Philip'; // OK
console.log(person1.name); // Philip

person1.age = 18; // Error, Seal object is non-extensible.
delete person1.name; // Error in strict mode.

冻结对象

使用Object.freeze()方法可以冻结一个对象,冻结后的对象不能添加、修改、删除属性,也不能修改属性的可枚举性、可配置性、可写性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'use strict';

const person1 = {
name: 'zdd',
};
console.log(Object.isFrozen(person1)); // false

Object.freeze(person1);
console.log(Object.isFrozen(person1)); // true

person1.name = 'ddz'; // Error. object is frozen.
person1.age = 18; // Cannot add property age, object is not extensible
delete person1.name; // TypeError: Cannot delete property 'name' of #<Object>

console.log(person1);

总结

特性 不可扩展对象 (Object.preventExtensions) 密封对象 (Object.seal) 冻结对象 (Object.freeze)
是否可新增属性 ❌ 不可新增 ❌ 不可新增 ❌ 不可新增
是否可修改属性值 ✅ 可修改 ✅ 可修改 ❌ 不可修改
是否可删除属性 ✅ 可删除 ❌ 不可删除 ❌ 不可删除
是否可更改原型链 ✅ 可更改 ✅ 可更改 ❌ 不可更改
是否可更改可枚举性 ✅ 可更改 ❌ 不可更改 ❌ 不可更改
是否可更改可配置性 ✅ 可更改 ❌ 不可更改 ❌ 不可更改
是否可更改可写性 ✅ 可更改 ✅ 可更改 ❌ 不可更改