js基础:花式获取对象属性和冻结对象

本文介绍的是一些获取对象属性和防止对象被修改的方法

获取对象属性

先定义一个对象

1
2
3
4
5
6
7
8
let obj = { a: 1, b: 2 }
obj.__proto__.name = 22
obj[Symbol()] = 33
Object.defineProperty(obj, 'cc', {
value: 'cc',
enumerable: false,
})
// {a: 1, b: 2, cc: "cc", Symbol(): 33} , obj.__proto__.name -> 22

各个方法

  1. for…in -> 遍历对象属性, 拿到可枚举的原型上的属性, 不能拿到 Symbol
1
2
3
4
5
6
for (key in obj) {
console.log(key)
}
// a
// b
// name
  1. Object.keys() -> 返回一个由一个给定对象的自身可枚举属性组成的数组, 不会拿到原型上的属性, 拿不到 Symbol
1
Object.keys(obj) // ["a", "b"]
  1. Object.values() -> 返回一个给定对象自身的所有可枚举属性值的数组, 不能拿到 Symbol
1
Object.values(obj) //[1, 2]
  1. Object.entries() -> 返回一个给定对象自身可枚举属性的键值对数组, 不会拿到原型上的属性
1
Object.entries(obj) // [["a", 1],["b", 2]]
  1. Object.getOwnPropertyNames() -> 返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括 Symbol值作为名称的属性)组成的数组
1
Object.getOwnPropertyNames(obj) // ["a", "b", "cc"]
  1. Object.getOwnPropertySymbols() -> 返回一个给定对象自身的所有 Symbol 属性的数组
1
Object.getOwnPropertySymbols(obj) //[Symbol()]
  1. Reflect.ownKeys() -> 返回一个由目标对象自身的所有属性键组成的数组, 包括不可枚举, Symbol
1
Reflect.ownKeys(obj) // ["a", "b", "cc", Symbol()]

冻结、密封对象

  1. 不可扩展对象 Object.preventExtensions

不可添加新属性

1
2
3
4
5
6
let obj = { a: 1, b: 2 }
Object.preventExtensions(obj)
obj.c = 1
obj // {a:1,b:2}
// Object.isExtensible检测是否可扩展
console.log(Object.isExtensible(obj)) // false
  1. 密封对象 Object.seal

密封对象不可扩展,而且已有的属性成员[[configurable]]特性将被设置成 false(意味着不能删除属性和方法,但是可修改已有属性值)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let obj = {
a: 'a',
b: [1, 2],
}
// 密封
Object.seal(obj)

// 删除
delete obj.a // false
// 可以删引用类型的属性
delete obj.b[1] // true.

obj.b // {a: "a", b: [1, empty]}
obj.b[1] // undefined

obj.a = 'c'
obj.a // c

// 查看描述, 可以看到configurable为false
Object.getOwnPropertyDescriptors(obj)
//a: {value: "a", writable: true, enumerable: true, configurable: false}
//b: {value: Array(2), writable: true, enumerable: true, configurable: false}
  1. 冻结对象 Object.freeze

最严格的防止篡改级别是冻结对象,冻结的对象既不可以扩展,又是密封的,而且对象数据属性的[[writable]]特性会被设置为 false。 如果定义[[Set]]函数,访问器属性仍然是可写的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let obj = {
a: 'a',
b: [1, 2],
}
Object.freeze(obj)

// 不可修改
obj.a = 'c'
obj.a // 'a'

// 不可删除
delete obj.a // false

// 不可新增
obj.c = 1

// 查看描述, 可以看到configurable为false, writable也为 false
Object.getOwnPropertyDescriptors(obj)
// a: {value: "a", writable: false, enumerable: true, configurable: false}
// b: {value: Array(2), writable: false, enumerable: true, configurable: false}

以上