重写数组方法

发布于 2022-12-30  25 次阅读


forEach

  • 第一个参数:cb(value, index, array)
    • 回调中 this 指向默认为 window
  • 第二个参数:指定回调中 this 指向

原生

var arr = [
  {
    name: 'Lance',
    age: 20,
  },
  {
    name: 'GC',
    age: 23
  },
  {
    name: 'Shank',
    age: 25
  }
];

var obj = {
  name: 'Lance',
  age: 23
}

arr.forEach(function(value, index, arr) {
  console.log(this); // 默认window
  console.log(value, index, arr);
}, obj);

实现

Array.prototype.myForEach = function(cb) {
	var _arr = this,
      _len = _arr.length,
      _caller = arguments[1] || window;

  for (var i = 0; i < _len; i++) {
  	cb.call(_caller, _arr[i], i, _arr);
  }
}

map

  • 和 forEach 类似,但是返回新数组
  • 如果数组成员是复杂类型(对象),那么在 cb 中修改 item,会改变原数组;如果数组成员是基本类型,则不会修改原数组
  • map没实现深拷贝

原生

var arr = [
  {
    name: 'Lance',
    age: 20,
  },
  {
    name: 'GC',
    age: 23
  },
  {
    name: 'Shank',
    age: 25
  }
];

var obj = {
  name: 'Lance',
  age: 23
}

var newArr = arr.map(function(item, index, arr) {
  item.name = this.name;
  return item; // 必须返回,否则数组里边成员都是 undefined
}, obj);
console.log(newArr, arr);

实现

Array.prototype.myMap = function(cb) {
	var _arr = this,
      _len = _arr.length,
      _caller = arguments[1] || window,
      newArr = [];

  for (var i = 0; i < _len; i++) {
    // var item = deepClone(_arr[i]); // 如果要实现深拷贝,可以加此行代码,同时把下边 _arr[i] 替换为 item
  	newArr.push(cb.call(_caller, _arr[i], i, _arr));
  }

  return newArr;
}

filter

  • 返回新数组
  • 原数组成员是复杂类型,cb 中修改也会影响原数组

原生

var arr = [
  {
    name: 'Lance',
    age: 20,
  },
  {
    name: 'GC',
    age: 23
  },
  {
    name: 'Shank',
    age: 25
  }
];

var obj = {
  name: 'Lance',
  age: 23
}

var newArr = arr.filter(function(item, index, arr) {
  console.log(item, index, arr, this);
  return item.age > 20;
}, obj);
console.log(newArr, arr);

实现

Array.prototype.myFilter = function(cb) {
	var _arr = this,
      _len = _arr.length,
      _caller = arguments[1] || window,
      newArr = [];

  for (var i = 0; i < _len; i++) {
    // var item = deepClone(_arr[i]); // 如果要实现深拷贝,可以加此行代码,同时把下边 _arr[i] 替换为 item
  	cb.call(_caller, _arr[i], i, _arr) && newArr.push(_arr[i]);
  }

  return newArr;
}

reduce

  • 返回一个“聚合”值
  • 没有第三个参数来指定cb中的this,始终为 window

原生

var arr = [
  {
    name: 'Lance',
    age: 20,
  },
  {
    name: 'GC',
    age: 23
  },
  {
    name: 'Shank',
    age: 25
  }
];

var obj = {
  name: 'Lance',
  age: 23
}

var newArr = arr.reduce(function(pre, item, index, arr) {
	item.age >= 23 && pre.push(item);
  return pre;
}, []);
console.log(newArr);

实现

Array.prototype.myReduce = function(cb, initialValue) {
	var _arr = this,
      _len = _arr.length,
      _caller = window;

  for(var i = 0; i < _len; i++) {
    // var item = deepClone(_arr[i]); // 如果要实现深拷贝,可以加此行代码,同时把下边 _arr[i] 替换为 item
  	initialValue = cb.call(_caller, initialValue, _arr[i], i, _arr);
  }

  return initialValue;
};

reduceRight

  • 遍历顺序和 reduce 相反,是从后往前遍历

原生

var arr = [
  {
    name: 'Lance',
    age: 20,
  },
  {
    name: 'GC',
    age: 23
  },
  {
    name: 'Shank',
    age: 25
  }
];

var obj = {
  name: 'Lance',
  age: 23
}

var newArr = arr.reduceRight(function(pre, item, index, arr) {
	item.age >= 23 && pre.push(item);
  return pre;
}, []);
console.log(newArr);

实现

Array.prototype.myReduceRight = function(cb, initialValue) {
	var _arr = this,
      _len = _arr.length,
      _caller = window;

  for(var i = _len - 1; i >= 0; i--) {
    // var item = deepClone(_arr[i]); // 如果要实现深拷贝,可以加此行代码,同时把下边 _arr[i] 替换为 item
  	initialValue = cb.call(_caller, initialValue, _arr[i], i, _arr);
  }

  return initialValue;
};

every

  • 返回 true or false
  • 所有 cb 结果都为 true 时,整体为 true
  • 只要有一个 cb 结果为 false,整体为 false

原生

var arr = [
  {
    name: 'Lance',
    age: 20,
  },
  {
    name: 'GC',
    age: 23
  },
  {
    name: 'Shank',
    age: 25
  }
];

var obj = {
  name: 'Lance',
  age: 23
}

var res = arr.every(function(item, index, arr) {
  return item.age < 23;
}, obj);
console.log(res);

实现

Array.prototype.myEvery = function(cb) {
	var _arr = this,
      _len = _arr.length,
      _caller = arguments[1] || window;

  for (var i = 0; i < _len; i++) {
    // var item = deepClone(_arr[i]); // 如果要实现深拷贝,可以加此行代码,同时把下边 _arr[i] 替换为 item
  	if (!cb.call(_caller, _arr[i], i, _arr)) {
    	return false;
    }
  }
  return true;
};

some

  • 返回 true or false
  • 只要有一个 cb 结果为 true,整体就为 true;否则为 false

原生

var arr = [
  {
    name: 'Lance',
    age: 20,
  },
  {
    name: 'GC',
    age: 23
  },
  {
    name: 'Shank',
    age: 25
  }
];

var obj = {
  name: 'Lance',
  age: 23
}

var res = arr.some(function(item, index, arr) {
  return item.age <= 20;
}, obj);
console.log(res);

实现

Array.prototype.mySome = function(cb) {
	var _arr = this,
      _len = _arr.length,
      _caller = arguments[1] || window;

  for (var i = 0; i < _len; i++) {
    // var item = deepClone(_arr[i]); // 如果要实现深拷贝,可以加此行代码,同时把下边 _arr[i] 替换为 item
  	if (cb.call(_caller, _arr[i], i, _arr)) {
    	return true;
    }
  }

  return false;
}
最后更新于 2023-07-20