Object
# 1. Object(any)
创建一个对象包装器,俗称装箱。
- null 与 undefined 返回空对象。
- 基本数据类型返回包装后的对象。
- 引用数据类型返回本身。
Object(null) // => {}
Object(undefined) // => {}
Object(7) => // => {7}
Object(7).valueOf() === 7 // => true
const reg = /7/
Object(reg) === reg // => true
2
3
4
5
6
7
8
# 2. Object.create(proto, options)
2006 年,Douglas Crockford 写了一篇文章:《JavaScript 中的原型式继承》 (opens new window)。ECMAScript 5 通过增加 Object.create() 方法将原型式继承的概念规范化了,第二个参数同 Object.defineProperties() 第二个参数。
本质上,object() 是对传入的对象执行了一次浅复制。Object.create() 只使用一个参数时与 object() 等价。
function object(o) {
function F() {}
F.prototype = o
return new F()
}
// 以下等价
const foo = {}
const foo = Object.create(Object.prototype)
const foo = object(Object.prototype)
// 创建完全为空的对象,无原型链
Object.create(null) // => {}
2
3
4
5
6
7
8
9
10
11
12
13
# 3. hasOwnProperty(prop)
检测自身是否拥有该属性,不包含原型链中的属性。
in 运算符会查找原型链中的可枚举属性。
function Skt() {}
Skt.prototype.faker = 3
const edg = new Skt()
edg.clearlove7 = 0
edg.hasOwnProperty('faker') // => false
edg.hasOwnProperty('clearlove7') // => true
'faker' in edg // => true
2
3
4
5
6
7
8
9
# 4. isPrototypeOf(object)
检测一个对象是否在其原型链上(Bar.isPrototypeOf(foo) 为检测 foo.__proto__ === Bar)。
instanceof 检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上(foo instanceof Bar 为检测 foo.__proto__ === Bar.prototype)。
Bar.prototype.isPrototypeOf(foo) 等价于 foo instanceof Bar。
function Foo() {}
const bar = new Foo()
Foo.prototype.isPrototypeOf(bar) // => true
Object.prototype.isPrototypeOf(bar) // => true
Function.prototype.isPrototypeOf(bar) // => false
bar instanceof Foo // => true
bar instanceof Object // => true
bar instanceof Function // => false
2
3
4
5
6
7
8
9
10
# 5. Object.assign(targetObject, object...)
将多个对象中可枚举属性合并至目标对象,属性名相同时会覆盖。
{...} 展开运算符可完全替代 Object.assign(),较 Object.assign() 有简便和性能上的优势。
const foo = {
name: '徐扶墙',
age: 17,
}
const bar = {
name: '姜姒',
}
Object.assign(foo, bar) // => {name: '姜姒', age: 17}
{...foo, ...bar} // => {name: '姜姒', age: 17}
// 传入可迭代对象
Object.assign({}, [1, 2, 3]) // => {0: 1, 1: 2, 2: 3}
Object.assign({}, 'neo') // => => {0: 'n', 1: 'e', 2: 'o'}
{...[1, 2, 3]} // => {0: 1, 1: 2, 2: 3}
{...'neo'} // => => {0: 'n', 1: 'e', 2: 'o'}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 6. Object.prototype.toString()
- 通过 Object.prototype.toString.call() 获取对象的类型(最全面的检测方式)。
const detectionType = value =>
typeof value === 'object'
? {}.toString.call(value).slice(8, -1).toLowerCase()
: typeof value
2
3
4
# 7. Object.setPrototypeOf(object, proto)
设置对象的原型(Object.setPrototypeOf(foo, bar) 等价于 foo.__proto__ = bar)。
由于更改对象的原型指向性能并不好,更推荐使用 Object.create() 创建新对象并设置其对象的原型。
function Foo() {}
Foo.prototype.matrix = 'neo'
// 以下等价
Object.setPrototypeOf({}, Foo.prototype)
Object.create(Foo.prototype)
({}).__proto__ = Foo.prototype
2
3
4
5
6
7
# 8. Object.getPrototypeOf(object)
- 获取对象的原型(Object.getPrototypeOf(bar) 获取 bar.__proto__)。
function Foo() {}
const bar = new Foo()
Object.getPrototypeOf(bar) === Foo.prototype // => true
2
3
4
# 9. Object.defineProperty(object, prop, options)
定义对象属性(Vue 2.x 数据响应式中应用此方法)。
当配置了 get() 或 set() 方法,value 和 writable 配置将会失效。
配置默认值是使用 Object.defineProperty() 定义属性时的默认值,若在 foo 中先定义 name 属性,则默认值 writable、enumerable、configurable 为 true。
const foo = {}
Object.defineProperty(foo, 'name', {
// 属性的值,默认undefined
value: '徐扶墙',
// 是否可写,默认false
writable: true,
// 是否可枚举,默认false
enumerable: true,
// 是否可配置,默认false
configurable: true,
// 获取属性时执行的方法
get() {
return '获取name值'
},
// 设置属性时执行的方法
set(newValue) {
return '设置name值'
},
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 10. Object.defineProperties(object, props)
- 与 Object.defineProperty() 用法类似,可以一次定义多个属性。
const foo = {}
Object.defineProperties(foo, {
name: {
value: '徐扶墙',
enumerable: true,
},
age: {
get() {
return '获取age值'
},
set(newValue) {
return '设置age值'
},
},
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 11. Object.getOwnPropertyDescriptor(object, prop)
- 获取自身对应属性的描述符。
const foo = {}
Object.defineProperty(foo, 'name', {
value: '徐扶墙',
writable: true,
})
Object.getOwnPropertyDescriptor(foo, 'name') // => {value: '徐扶墙', writable: true, enumerable: false, configurable: false}
2
3
4
5
6
7
8
# 12. Object.getOwnPropertyDescriptors(object)
- 获取自身所有属性的描述符。
const foo = {}
Object.defineProperties(foo, {
name: {
value: '徐扶墙',
enumerable: true,
},
age: {
get() {
return '获取age值'
},
set(newValue) {
return '设置age值'
},
},
})
Object.getOwnPropertyDescriptors(foo) // => {name: {value: '徐扶墙', writable: false, enumerable: true, configurable: false}, age: {enumerable: false, configurable: false, get: ƒ, set: ƒ}}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 13. propertyIsEnumerable(prop)
- 检测属性是否可枚举。
const foo = {}
Object.defineProperties(foo, {
name: {
value: '徐扶墙',
enumerable: true,
},
age: {
get() {
return 17
},
},
})
foo.propertyIsEnumerable('name') // => true
foo.propertyIsEnumerable('age') // => false
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 14. Object.keys(object) & Object.values(object) & Object.entries(object)
- 返回由对象自身 key/value/[key, value] 组成的数组,不包含不可枚举属性。
const foo = {}
Object.defineProperties(foo, {
name: {
value: '徐扶墙',
enumerable: true,
},
age: {
enumerable: true,
get() {
return 17
},
},
wife: {
value: '裴南苇',
},
})
Object.keys(foo) // => ['name', 'age']
Object.values(foo) // => ['徐扶墙', 17]
Object.entries(foo) // => [['name', '徐扶墙'], ['age', 17]]
Object.keys([1, 2, 3]) // => ['0', '1', '2']
Object.values('neo') // => ['n', 'e', 'o']
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 15. Object.getOwnPropertyNames()
- 返回自身属性组成的数组,包含不可枚举属性。
const foo = {}
Object.defineProperties(foo, {
name: {
value: '徐扶墙',
enumerable: true,
},
age: {
enumerable: true,
get() {
return 17
},
},
wife: {
value: '裴南苇',
enumerable: false,
},
})
Object.getOwnPropertyNames(foo) // => ['name', 'age', 'wife']
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 16. Object.fromEntries(iterable)
- 将键值对列表转换为一个对象。
Object.fromEntries(Object.entries({ name: '徐扶墙', age: 17 })) // => {name: '徐扶墙', age: 17}
Object.fromEntries(
new Map([
['name', '徐扶墙'],
['age', 17],
])
) // => {name: '徐扶墙', age: 17}
2
3
4
5
6
7
8
# 17. Object.getOwnPropertySymbols(object)
- 返回自身的所有的 Symbol 属性组成的数组。
const foo = {
[Symbol('name')]: '徐扶墙',
[Symbol('age')]: 17,
wife: '裴南苇',
}
Object.getOwnPropertySymbols(foo) // => [Symbol(name), Symbol(age)]
2
3
4
5
6
7
# 18. Object.is(value, value)
- 最准确的比较方式,效率不高,主要用来解决下面两种情况(NaN 可用 Number.isNaN() 方法判断)。
Object.is(+0, -0) // => false
Object.is(NaN, NaN) // => true
+0 === -0 // => true
NaN === NaN // => false
2
3
4
5
# 19. Object.preventExtensions(object)
- 浅禁止对象扩展,可删除属性,可重新配置(Object.defineProperty() | Object.defineProperties())。
const foo = {
name: '徐扶墙',
harem: {
bigWife: '姜姒',
},
}
Object.preventExtensions(foo)
foo.age = 17
foo.harem.smallWife = '裴南苇'
delete foo.harem.bigWife // => true
console.log(foo) // => {name: '徐扶墙', harem: {smallWife: '裴南苇'}}
2
3
4
5
6
7
8
9
10
11
12
# 20. Object.isExtensible(object)
- 判断对象是否可扩展。
const foo = {
name: '徐扶墙',
age: 17,
harem: {
bigWife: '姜姒',
smallWife: '裴南苇',
},
}
Object.preventExtensions(foo)
Object.isExtensible(foo) // => false
Object.isExtensible(foo.harem) // => true
2
3
4
5
6
7
8
9
10
11
12
# 21. Object.seal(object)
- 浅密封对象,不可扩展,不可删除属性,不可重新配置(Object.defineProperty() | Object.defineProperties())。
const foo = {
name: '徐扶墙',
harem: {
bigWife: '姜姒',
smallWife: '裴南苇',
},
}
Object.seal(foo)
foo.age = 17
delete foo.name // => false
delete foo.harem.smallWife // => true
console.log(foo) // => {name: '徐扶墙', harem: {bigWife: '姜姒'}}
2
3
4
5
6
7
8
9
10
11
12
13
# 22. Object.isSealed(object)
- 判断对象是否密封。
const foo = {
name: '徐扶墙',
age: 17,
harem: {
bigWife: '姜姒',
smallWife: '裴南苇',
},
}
Object.seal(foo)
Object.isSealed(foo) // => true
Object.isSealed(foo.harem) // => false
2
3
4
5
6
7
8
9
10
11
12
# 23. Object.freeze(object)
- 浅冻结对象,不可增删改对象属性,不可从新配置(Object.defineProperty() | Object.defineProperties())。
const foo = {
name: '徐扶墙',
age: 17,
harem: {
bigWife: '姜姒',
smallWife: '裴南苇',
},
}
Object.freeze(foo)
foo.rank = '天下第二' // => 无效
foo.age = 18 // => 无效
delete foo.name // => false
foo.harem.smallWife = '白狐儿脸' // => 有效
console.log(foo) // => { name: '徐扶墙', age: 17, harem: { bigWife: '姜姒', smallWife: '白狐儿脸' } }
// 深度冻结
function deepFreeze(obj) {
const values = Object.values(obj)
if (values.length)
values.forEach(val => {
if (typeof val === 'object' && val !== null) deepFreeze(val)
})
return Object.freeze(obj)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 24. Object.isFrozen(object)
- 判断是否为冻结对象。
const foo = {
name: '徐扶墙',
age: 17,
harem: {
bigWife: '姜姒',
smallWife: '裴南苇',
},
}
Object.freeze(foo)
Object.isFrozen(foo) // => true
Object.isFrozen(foo.name) // => true
Object.isFrozen(foo.harem) // => false
2
3
4
5
6
7
8
9
10
11
12
13
14