arrayLikeKeys

"I'm not in this world to live up to your expectations and you're not in this world to live up to mine." —Bruce Lee

本文为 《lodash 源码阅读》 系列文章,后续内容会在 githubarrow-up-right 中发布,欢迎 star,gitbookarrow-up-right 同步更新。

依赖

import isArguments from '../isArguments.js';
import isBuffer from '../isBuffer.js';
import isIndex from './isIndex.js';
import isTypedArray from '../isTypedArray.js';

源码

const hasOwnProperty = Object.prototype.hasOwnProperty;

/**
 * 创建类数组 `value` 的可枚举属性名的数组。
 *
 * @private
 * @param {*} value 要查询的值。
 * @param {boolean} inherited 是否返回继承属性名。
 * @returns {Array} 返回属性名数组。
 */
function arrayLikeKeys(value, inherited) {
  // 判断是否为数组类型
  const isArr = Array.isArray(value);
  // 判断是否为非数组且为 arguments 类型
  const isArg = !isArr && isArguments(value);
  // 判断是否为非数组、非 arguments 且为 buffer 类型
  const isBuff = !isArr && !isArg && isBuffer(value);
  // 判断是否为非数组、非 arguments、非 buffer 且为 typed  类型
  const isType = !isArr && !isArg && !isBuff && isTypedArray(value);
  const skipIndexes = isArr || isArg || isBuff || isType;
  const length = value.length;

  // 创建 result 变量缓存类数组索引属性值
  const result = new Array(skipIndexes ? length : 0);
  let index = skipIndexes ? -1 : length;
  while (++index < length) {
    result[index] = `${index}`;
  }

  // 遍历 value 属性值,根据 inherited 判断是否返回继承属性名,并跳过重复添加索引属性值
  for (const key in value) {
    if (
      // 判断是否添加继承属性名。
      (inherited || hasOwnProperty.call(value, key)) &&
      !(
        skipIndexes &&
        // Safari 9 严格模式中 `arguments.length` 是可枚举属性
        (key == 'length' ||
          // 跳过索引属性值
          isIndex(key, length))
      )
    ) {
      result.push(key);
    }
  }
  return result;
}

相关链接

Last updated

Was this helpful?