JS基础(2)——手写数组原型函数 之 不改变原数组(filter,find,findIndex,some,every,map,forEach,reduce)

JS基础(2)——手写数组原型函数 之 不改变原数组(filter,find,findIndex,some,every,map,forEach,reduce)

1、模板

Array.prototype.myFunction = function(callback, thisArg) {
  if(this == undefined){
    throw new TypeError('this is null or not defined');
  }
  if(typeof callback !== 'function') {
    throw new TypeError(callback + 'is not a function');
  }
  if (!Array.isArray(this)) {
    throw new TypeError(this + ' is not an Array');
  }
  thisArg = thisArg || this;
  // 具体的code
  // callback.call(thisArg, this[i], i, this)
  // callback函数的调用形式
  return res;
}

后面部分代码省略通用部分

2、Array.prototype.filter

参数 callback(element,index,array) thisArg

返回值:新数组

(1)转化为对象,遍历对象

Array.prototype.myFilter = function(callback, thisArg) {
  if(this == undefined){
    throw new TypeError('this is null or not defined');
  }
  if(typeof callback !== 'function') {
    throw new TypeError(callback + 'is not a function');
  }
  if (!Array.isArray(this)) {
    throw new TypeError(this + ' is not an Array');
  }
  thisArg = thisArg || this;
  // 下列代码可替换
  const res = [];
  // 让Obj成为回调函数的对象传递(强制转换对象)
  const Obj = Object(this);
  // >>>0 保证len为number,且为正整数
  const len = Obj.length >>> 0;
  for(let i = 0;i < len; i++){
    // 检查i是否在Obj的属性(会检查原型链)
    if(i in Obj){
      // 回调函数调用传参
      if(callback.call(thisArg, Obj[i], i, Obj)){
        res.push(Obj[i]);
      }
    }
  }
  return res;
}

什么时候this会是undefined?

(2)数组本身+for循环

Array.prototype.myFilter2 = function(callback, context){
  // code同上
  const len = this.length,
        res = [];
  for(let i = 0; i < len; i++){
    if(callback.call(context, this[i], i, this)){
      res.push(this[i]);
    }
  }
  return res;
}

(3)用forEach

Array.prototype.myFilter3 = function(callback,context) {
  // code同上
  const res = [];
  this.forEach((item, index) => {
    if(callback.call(context, item, index, this)){
      res.push(item);
    }
  })
  return res;
}

3、Array.prototype.find

find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。

注意:1,返回第一个满足要求的值,否则返回undefined。2,不改变原数组

语法:arr.find(callback[, thisArg]);

Array.prototype.myFind = function(callback, thisArg) {
  if(this == undefined){
    throw new TypeError('this is null or not defined');
  }
  if(typeof callback !== 'function') {
    throw new TypeError(callback + 'is not a function');
  }
  if (!Array.isArray(this)) {
    throw new TypeError(this + ' is not an Array');
  }
  thisArg = thisArg || this;
  const Obj = Object(this),
        len = Obj.length;
  for (let i = 0; i < len; i++){
    if(fn.call(thisArg, Obj[i], i, this)){
      return Obj[i];
    }
  }
  return undefined;
}

4、Array.prototype.findIndex

findIndex() 方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回 -1。

注意:1,返回第一个满足要求的索引,否则返回-1。2,不改变原数组

语法:arr.find(callback[, thisArg]);

Array.prototype.myFindIndex = function(callback, thisArg) {
    if(this == undefined){
        throw new TypeError('this is null or not defined');
    }
    if(typeof callback !== 'function') {
        throw new TypeError(callback + 'is not a function');
    }
    if (!Array.isArray(this)) {
        throw new TypeError(this + ' is not an Array');
    }
    thisArg  = thisArg || this;
    const Obj = Object(this),
          len = Obj.length;
    for (let i = 0; i < len; i++){
        if(fn.call(thisArg, Obj[i], i, this)){
            return i;
        }
    }
    return -1;
}

5、Array.prototype.some

返回值:若数组中存在元素,满足提供的测试函数,则返回true。否则返回false。

注意:不改变原数组

语法:arr.find(callback[, thisArg]);

Array.prototype.mySome = function(callback, thisArg) {
    if(this == undefined){
        throw new TypeError('this is null or not defined');
    }
    if(typeof callback !== 'function') {
        throw new TypeError(callback + 'is not a function');
    }
    if (!Array.isArray(this)) {
        throw new TypeError(this + ' is not an Array');
    }
    thisArg  = thisArg || this;
    const Obj = Object(this),
          len = Obj.length;
    for (let i = 0; i < len; i++){
        if(fn.call(thisArg, Obj[i], i, this)){
            return true;
        }
    }
    return false;
}

6、Array.prototype.every

返回值:若数组中每个元素,都满足提供的测试函数,则返回true。否则返回false。

注意:不改变原数组

语法:arr.find(callback[, thisArg]);

Array.prototype.myEvery = function(callback, thisArg) {
    if(this == undefined){
        throw new TypeError('this is null or not defined');
    }
    if(typeof callback !== 'function') {
        throw new TypeError(callback + 'is not a function');
    }
    if (!Array.isArray(this)) {
        throw new TypeError(this + ' is not an Array');
    }
    thisArg  = thisArg || this;
    const Obj = Object(this),
          len = Obj.length;
    for (let i = 0; i < len; i++){
        if(!fn.call(thisArg, Obj[i], i, this)){
            return false;
        }
    }
    return true;
}

7、Array.prototype.map

参数 callback(currentValue,index,array) thisArg

返回值 原数组

Array.prototype.myMap = function(callback, thisArg){
  if(this == undefined){
    throw new TypeError('this is null or not defined');
  }
  if(typeof callback !== 'function'){
    throw new TypeError(callback + ',callback is not a function');
  }
  if (!Array.isArray(this)) {
    throw new TypeError(this + ' is not an Array');
  }
  thisArg = thisArg || this;
  const res = [],
        len = this.length;
  for(let i = 0; i < len; i++){
    const cur = callback.call(thisArg, this[i], i, this);
    res.push(cur);
  }
  return res;
}     
Array.prototype.map = function(callback, thisArg) {
  // code同上
  const res = [],
        Obj = Object(this),
        len = Obj.length >>> 0;
  for(let i = 0;i < len; i++){
    if(i in Obj){
      res[i] = callback.call(thisArg, Obj[i], i, this);
    }
  }
  return res;
}

8、Array.prototype.forEach

参数 callback(currentValue,index,array) thisArg

返回值 undefined

Array.prototype.forEach = function(callback, thisArg) {
  if(this == null){
    throw new TypeError('this is null or not defined');
  }
  if(typeof callback !== 'function') {
    throw new TypeError(callback + 'is not a function');
  }
  if (!Array.isArray(this)) {
    throw new TypeError(this + ' is not an Array');
  }
  thisArg = thisArg || this;
  const Obj = Object(this),
        len = Obj.length >>> 0;
  for(let k = 0; k < len; k++){
    if(k in Obj){
      callback.call(thisArg, Obj[k], k, Obj);
    }
  }
}

9、Array.prototype.reduce

参数 callback(accumulator,currentValue,index,array) initialValue

返回值 函数累计处理的结果

Array.prototype.myReduce1 = function(callback, initialValue){
    if(this == undefined){
        throw new TypeError('this is null or not defined');
    }
    if(typeof callback !== 'function'){
        throw new TypeError(callback + ', callback is not a function');
    }
    if(!Array.isArray(this)){
        throw new TypeError(this + '  is not an Array');
    }
    const obj = Object(this),
          len = obj.length >>> 0;
    let accumulator = initialValue,
        k = 0;
    if(accumulator == undefined){
        while(k < len && !k in obj){
            k++;
        }
        if(k >= len){
            throw new TypeError('Reduce of empty array with no initial value');
        }
        accumulator = obj[k++];
    }
    while(k < len){
        if(k in obj){
            accumulator = callback.call(undefined, accumulator, obj[k], k, obj);
        }
        k++;
    }
    return accumulator;
}
Array.prototype.myReduce1 = function(callback, initialValue){
    // code同上
    const len = this.length;
    if(len <= 0){
        throw new TypeError('Reduce of empty array with no initial value');
    }
    let i = 0;
    let accumulator = initialValue || this[i++];
    while(i < len){
        accumulator = callback.call(undefined, accumulator, this[i], i, this);
        i++;
    }
    return accumulator;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值