数组各个方法的实现原理

76 阅读2分钟

1. push方法的实现原理

Array.prototype.myPush = function(...elements){
    for(let i = 0; i <elements.length;i++) {
      this[this.length] = elements[i];
    }
}

2. filter方法的实现原理

Array.prototype.myFilter = function(callback, thisArg) {
  if (typeof callback !== 'function') {
    throw new TypeError(callback + ' is not a function');
  }
  
  const result = [];
  
  for (let i = 0; i < this.length; i++) {
    // 检查是否是该数组的真实属性(跳过稀疏数组的空位)
    if (i in this) {
      // 调用回调函数,可以绑定 thisArg
      const testResult = callback.call(thisArg, this[i], i, this);
      if (testResult) {
        result.push(this[i]);
      }
    }
  }
  
  return result;
};

3. find方法的实现原理

filter方法学会了, find方法是一样的道理

Array.prototype.myFind = function(callback, thisArg) {
  if (typeof callback !== 'function') {
    throw new TypeError(callback + ' is not a function');
  }
  
  for (let i = 0; i < this.length; i++) {
    if (i in this) {
      if (callback.call(thisArg, this[i], i, this)) {
        return this[i];
      }
    }
  }
  // 没有找到时隐式返回 undefined
};

4. map方法的实现原理

Array.prototype.myMap = function(callback, thisArg) {
    // 判断callback是否为函数
    if(typeof callback !== 'function') {
        throw new TypeError('callback must be a function');
    }
   
    // 将this转换为对象
    const O = Object(this);
  
    // 获取数组长度(使用无符号右移操作符确保len为数字且为正整数)
    const len = O.length >>> 0;

    const result = [];
    
    for(let i = 0; i < len; i++) {
        // 检查当前索引是否存在于数组中(处理稀疏数组)
        if(i in this) {
            result.push(callback.call(thisArg, this[i], i, this));
        }
    }
    return result;
};

5. reduce方法的实现原理

Array.prototype.myReduce = function(callback, initialValue) {
  if (this == null) {
    throw new TypeError('Array.prototype.myReduce called on null or undefined');
  }
  if (typeof callback !== 'function') {
    throw new TypeError(callback + ' is not a function');
  }

  const array = Object(this); // 确保是数组或类数组对象
  const length = array.length >>> 0; // 转换为无符号整数(处理非数字 length)
  
  let accumulator;
  let startIndex = 0;

  // 1. 处理初始值
  if (initialValue !== undefined) {
    accumulator = initialValue;
  } else {
    // 无初始值时,取第一个元素作为初始值,从第二个元素开始遍历
    if (length === 0) {
      throw new TypeError('Reduce of empty array with no initial value');
    }
    accumulator = array[0];
    startIndex = 1;
  }

  // 2. 遍历数组并累积
  for (let i = startIndex; i < length; i++) {
    if (i in array) { // 跳过稀疏数组的空位
      accumulator = callback(accumulator, array[i], i, array);
    }
  }

  return accumulator;
};