开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
数组与对象转换有哪些方式?
对象转换成数组有四种方式:
Object.keysObject.valuesObject.entriesfor in
数组转换成对象则通过 Object.fromEntries 实现。
const zoo = {
lion: '🦁',
panda: '🐼',
};
Object.keys(zoo);
// ['lion', 'panda']
Object.values(zoo);
// ['🦁', '🐼']
const arr = Object.entries(zoo);
// [ ['lion', '🦁'], ['panda', '🐼'] ]
// 数组转换成对象
Object.fromEntries(array);
// {
// lion: '🦁',
// panda: '🐼',
// }
const numbers = {
one: 1,
two: 2,
};
const keys = [];
// 通过 for in 遍历对象
for (const number in numbers) {
if (numbers.hasOwnProperty(number)) {
keys.push(number);
}
}
keys; // [ 'one', 'two' ]
Object.keys 存在哪些问题?
不能保证 Object.keys 返回的字段顺序。
JS 中对象的属性是无序的,所以 Object.keys 迭代的顺序依赖于浏览器实现。不同的浏览器实现的方式也不一样。
keys 数组分为三个规则进行排序:
- 可以作为数组索引的 key 按照升序。
- 字符串按照创建顺序排列。
symbol类的 key 按照创建顺序排列。
如何保证对象属性的顺序?
通过 ownPropertyKeys 对象属性遍历的顺序。
基于内部 ownPropertyKeys 方法实现的方法有 Object.getOwnPropertyNames 和 Reflect.ownKeys,这两种方法保证对象属性的顺序。
Reflect.ownKeys 有兼容性问题,但是可以打印出 Symbol 的属性。
const key = Symbol('text');
const obj = {
name: 'kane',
1: 988,
age: '18',
[key]: 'hi',
[Symbol('test')]: 'Symbol test',
[Symbol.for('fn')]: () => 'symbol fn'
}
Object.keys(obj)
Object.getOwnPropertyNames(obj)
// 查看属性
Reflect.ownKeys(obj)
// 获取对象的 symbol 属性
obj[Object.getOwnPropertySymbols(obj)[0]]
// 调用对象的 symbol 方法
console.log(obj[Symbol.for('fn')]())
如何判断空对象?
const empty = {};
Object.keys(empty).length === 0 && empty.constructor === Object
// true
为什么还需要 constructor 进行判断? 众所周知在JS中一切皆对象 增加 constructor 进行判断是为了覆盖包装器实例。
// bad case
function emptyCheck(value) {
return Object.keys(value).length === 0;
}
emptyCheck(new String()); // true
emptyCheck(new Number()); // true
emptyCheck(new Boolean()); // true
emptyCheck(new Array()); // true
emptyCheck(new RegExp()); // true
emptyCheck(new Function()); // true
emptyCheck(new Date()); // true
如果将函数拓展成公共方法 isEmpty,还需要增加对 null undefined 的判断。
function emptyCheck(value) {
return value && Object.kObject.keys(empty).length === 0 && empty.constructor === Object
}
// Empty Object Check in Older Browsers
function isObjectEmpty(value) {
return (
Object.prototype.toString.call(value) === '[object Object]' &&
JSON.stringify(value) === '{}'
);
}