js数组方法重写——pop、push、shift、unshift、every、some、filter、map、forEach

js中给我们提供了很多数组API,比如pop、push、filter、map等,这些都是别人写好的,放在数组的原型对象上,供我们使用。我们也可以对这些方法进行重写,这样可以加深我们对这些数组方法的理解。

数组方法的详细介绍可以看这里:https://blog.csdn.net/LQ313131/article/details/126315166

下面我们对这些方法进行重写:

pop

pop() 方法用于删除数组的最后一个元素,并返回删除的元素。
没有参数,会修改原数组,数组为空时返回 undefined

思路:
我们想要删除数组元素,就要获取到该数组,那么我们如何获取该数组呢?
由于数组调用了pop()方法,因此 this 指向该数组。

获取到该数组之后,我们需要做的就是:
当数组为空时,返回 undefined;
当数组不为空时,先获取最后一个元素的值作为返回值,再删除。

var arr = [18, 23, 44, 63, 17]
Array.prototype.myPop = function(){
  if(this.length){
    //获取数组最后一个元素的值作为返回值
    var last = this[this.length - 1]
    //删除最后一个元素
    this.length -= 1
    return last
  }else{
    //空数组返回 undefined
    return undefined
  }
  
}
console.log(arr.myPop()); //17
console.log(arr); //[ 18, 23, 44, 63 ]

push

push() 方法可向数组的末尾添加一个或多个元素,并返回新的数组长度。
有参数,会修改原数组。

思路:我们要如何获取需要添加的元素,即如何获取push()的参数?
函数中有一个类数组对象 arguments 可以获取到函数的实参。

获取到了需要添加的元素之后,我们只需要把它们遍历添加到数组尾部即可。

Array.prototype.myPush = function(){
  //循环遍历需要添加的元素
  for(var i = 0; i < arguments.length; i++){
    //向数组末尾添加元素
    this[this.length] = arguments[i]
  }
  return this.length
}
console.log(arr.myPush(1, 2)); //7
console.log(arr); //[18, 23, 44, 63, 17, 1, 2]

shift

shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。
没有参数,修改原数组。

思路:想要删除第一个元素,我们只需要把第二个以后的元素往前移一位,然后再让数组长度减一即可。

var arr = [18, 23, 44, 63, 17]
Array.prototype.myShift = function(){
  var first = this[0]
  for(var i = 0; i < this.length; i++){
  //让元素往前移一位
    this[i] = this[i+1]
  }
  this.length -= 1
  return first
}
console.log(arr.myShift()); //18
console.log(arr); //[ 23, 44, 63, 17 ]

unshift

unshift() 方法可向数组的开头添加一个或更多元素,并返回新的数组长度。
有参数,修改原数组。

思路:要添加几个元素,我们就让原数组元素往后移几位,然后将要添加的元素添加到前面。

var arr = [18, 23, 44, 63, 17]
Array.prototype.myUnshift = function () {
  //计算新数组长度
  var newLength = this.length + arguments.length
  for (var i = newLength; i > 0; i--) {
    if (i > arguments.length) {
      //原数组元素后移
      this[i - 1] = this[i - 1 - arguments.length]
    } else {
      //添加新元素
      this[i - 1] = arguments[i - 1]
    }
  }
  return newLength
}
console.log(arr.myUnshift(1, 2)); //7
console.log(arr); //[1, 2, 18, 23, 44, 63, 17]

every

every() 方法使用指定函数检测数组中的所有元素:
1、如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
2、如果所有元素都满足条件,则返回 true。

every() 方法有两个有意义的参数,第一个是回调函数(它又有三个参数,分别表示:数组元素的值、索引值、数组本身);第二个用来指定回调函数的this指向,这里我们可以使用call、apply或者bind方法来绑定this指向。

思路:我们使用循环遍历数组,将参数传给回调函数,又因为回调函数返回的是布尔值,因此我们可以使用它作为判断条件。

var arr = [23, 44, 63, 10, 17]
Array.prototype.myEvery = function (fn) {
  // console.log(arguments[1]);
  // console.log(fn.call(arguments[1], this[1], 0, [18, 23, 44, 63, 17])); //true
  for(var i = 0; i < this.length; i++){
  //fn.call(arguments[1], this[i], i, this) 表示执行函数fn,fn返回值为false或true
  //当有一个不满足条件时,就跳出循环,返回false
    if(! fn.call(arguments[1], this[i], i, this)){
      return false
    }
  }
  return true
}

var res = arr.myEvery(function(item, index, array){
  console.log(item + '-' + index + '-' + array);
  return item > 20
})
console.log(res); //false

some

some() 方法会依次执行数组的每个元素:
1、 如果有一个元素满足条件,则表达式返回 true , 剩余的元素不会再执行检测。
2、如果没有满足条件的元素,则返回 false。

some()方法和every()类似,不同在于 some()方法只要有一个满足条件就返回true,而every()方法只要有一个不满足就返回false。

var arr = [23, 44, 63, 10, 17]
Array.prototype.mySome = function (fn) {
  // console.log(arguments[1]);
  // console.log(fn.call(arguments[1], this[1], 0, [18, 23, 44, 63, 17])); //true
  for(var i = 0; i < this.length; i++){
  //fn.call(arguments[1], this[i], i, this) 表示执行函数fn,fn返回值为false或true
  //只要有一个满足条件,就跳出循环,返回true
    if(fn.call(arguments[1], this[i], i, this)){
      return true
    }
  }
  return false
}

var res = arr.mySome(function(item, index, array){
  console.log(item + '-' + index + '-' + array);
  return item == 17
})
console.log(res); //true

filter

filter() 方法找出满足条件的数组元素,以数组的形式返回。

var arr = [18, 23, 44, 63, 17]
Array.prototype.myFilter = function(fn){
  //定义一个数组变量存放满足条件的元素
  var newArr = []
  for(var i = 0; i < this.length; i++){
    //将满足条件的元素放到数组中
    if(fn.call(arguments[1], this[i], i, this)){
      newArr[newArr.length] = this[i]
    }
  }
  return newArr
}
var res = arr.myFilter(function(item){
  return item > 20 //找出大于20的元素
})
console.log(res); //[ 23, 44, 63 ]

map

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

思路:map()方法的回调函数的返回值不再是布尔值,它返回的值就是对原数组元素处理后的值,因此我们可以直接将它返回值存放到新的数组中,然后返回新数组即可。

var arr = [18, 23, 44, 63, 17]
Array.prototype.myMap = function(fn){
  //定义一个新数组,存放处理后的数组元素的值
  var newArr = []
  // console.log(fn.call(arguments[1], this[1], 1, this));
  for(var i = 0; i < this.length; i++){
    newArr[newArr.length] = fn.call(arguments[1], this[i], i, this)
  }
  return newArr
}
var res = arr.myMap(function(item){
  return item + 1 //将数组中的每一项做加1操作
})
console.log(res); //[ 19, 24, 45, 64, 18 ]
console.log(arr); //[ 18, 23, 44, 63, 17 ]

forEach

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

思路:这里我们只需要循环遍历数组,将参数传给回调函数执行即可,不需要做其他操作。

var arr = [18, 23, 44, 63, 17]
Array.prototype.myForEach = function(fn){
  for(var i = 0; i < this.length; i++){
    fn.call(arguments[1], this[i], i, this)
  }
}
var sum = 0
var res = arr.myForEach(function(item){
  sum += item //求数组元素之和
})
console.log(sum); //165
console.log(arr); //[ 18, 23, 44, 63, 17 ]
  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值