开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
数组与对象转换有哪些方式?
对象转换成数组有四种方式:
Object.keys
Object.values
Object.entries
for 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) === '{}' ); }