【若川视野 x源码共读】第33期 | arrify 转数组 Convert a value to an array

102 阅读1分钟

持续创作,加速成长!这是我第一次参与「掘金日新计划 · 6 月更文挑战」,点击查看活动详情

本文参加了由公众号@若川视野 发起的每周源码共读活动,点击了解详情一起参与。

1.arrify源码解析

(1) 传入一个参数value , 得到相对应的一个数组。

(2) 对于 null undefined类型, 返回空数组 [];对于 array类型, 返回原数组;
对于 string类型, 处理成数组,采用[value]的形式。

2.arrify源码

function arrify(value) {
  if (value === null || value === undefined) {
    return [];
  }

  if (Array.isArray(value)) {
    return value;
  }

  // 因为字符串具有 Symbol.iterator接口,所以先处理
  if (typeof value === 'string') {
    return [value];
  }

  // 处理 Map、Set类型的数据(根据具有实现的 Simbol.iterator接口)
  if (typeof value[Symbol.iterator] === 'function') {
    return [...value];
  }

  return [value];
}

3.switch接手if

function arrify(value) {
  switch (true) {
    case value == null:
      return [];
    case Array.isArray(value):
      return value;
    case typeof (value) === 'string':
      return [value];
    case typeof (value[Symbol.iterator]) === 'function':
      return [...value];
    default:
      return [value];
  }
}

4.魔改(让代码超越脑子)

/**                    码值
 * null/undefined      1000
 * []                  0100
 * 'hello'             0011 | 0010
 * set()               0001
 * other               0000
*/
function arrify(value) {
  const ascTable = {
    '0000': [value],
    '1000': [],
    '0100': value,
    '0011': [value],
    '0010': [value],
    '0001': (typeof (value && value[Symbol.iterator]) === 'function') && [...value]
  } 
  const asc = '' + +(value == null) + +(Array.isArray(value)) + +(typeof (value) === 'string') + +(typeof (value && value[Symbol.iterator]) === 'function');
  return ascTable[asc];
}

5.示例

const map = new Map([
  [1, 2],
  [3, 4],
]);
console.log(arrify(map));  // [[1, 2], [3, 4]]
console.log(arrify());  // []
console.log(arrify(null));  // []
console.log(arrify(undefined));  // []
const set = new Set([1, 2, 3, 4]);
console.log(arrify(set));  // [1, 2, 3, 4]
console.log(arrify('hello world')); // ['hello world']
console.log(arrify(NaN));  // [NaN]
console.log(arrify(0));  // [0]
console.log(arrify(''));  // ['']
console.log(arrify(false));  // [false]