最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • js数组所有内置方法简述以及手动实现(二)

    正文概述 掘金(nathan_ll)   2020-12-13   427

    写在前面

    第二篇来啦!冲!冲!冲!

    第一篇在这里js数组所有内置方法简述以及手动实现(一)

    因为有一次面试碰到了问有没有用过数组所有的内置方法?、是否清楚所有内置方法的参数和使用?当时并没有能全部答出来,所以决定从头理一篇所有的数组内置方法,并且自己实现一遍。主要是知识梳理,读者们也能从头梳理一遍。下面的方法尽量会全部自己实现,实在有困难的会google,然后注明出处。所有源码在GITHUB。

    indexOf()

    搜索数组中的元素,并返回它所在的位置。

    例子?

    let a = [1,2,3,NaN]
    a.indexOf(2) // 1
    

    实现

    Array.prototype.indexOf2 = function (el, start = 0) {
      if (start >= this.length || start < 0) return -1
      for (let i = start; i < this.length; i++) {
        if (el === this[i]) {
          return i
        }
      }
      return -1
    }
    

    isArray()

    判断对象是否为数组。

    例子?

    let a = [1,2,3,NaN]
    Array.isArray(a) // true
    

    实现

    Array.isArray2 = function (array) {
      return Object.prototype.toString.call(arg) === '[object Array]'
    }
    

    join()

    把数组的所有元素放入一个字符串。

    例子?

    let a = [1,2,3,NaN]
    a.join(',') // '1,2,3,NaN'
    

    实现

    Array.prototype.join2 = function (separator = '') {
      let res
      for (let i = 0; i < this.length; i++) {
        if (!res) {
          res = this[i]
        } else {
          res += separator + this[i]
        }
      }
      return res
    }
    

    keys()

    返回数组的可迭代对象,包含原始数组的键(key)。

    例子?

    let a = [1,2,3,NaN]
    let b = a.keys()
    b.next() //{value: 0, done: false}
    b.next() //{value: 1, done: false}
    b.next() //{value: 2, done: false}
    b.next() //{value: 3, done: false}
    b.next() //{value: undefiend, done: true}
    

    实现

    function makeIterator(array) {
      let nextIndex = 0;
      return {
        [Symbol.iterator]: function() {
          return nextIndex < array.length ?
            {value: array[nextIndex++], done: false} :
            {value: undefined, done: true};
        }
      };
    }
    
    Array.prototype.keys2 = function () {
      let res = []
      for (let i = 0; i < this.length; i++) {
        res.push(i)
      }
      return makeIterator(res).Symbol.iterator
    }
    

    迭代器详情请看阮一峰老师的ECMAScript 6 入门-Iterator 和 for...of 循环

    lastIndexOf()

    搜索数组中的元素,并返回它最后出现的位置。

    例子?

    var fruits = ["Banana", "Orange", "Apple", "Mango"];
    fruits.lastIndexOf("Apple"); // 2
    

    实现

    Array.prototype.lastIndexOf2 = function (el, start = 0) {
      start = Math.abs(start)
      let res = -1
      for (let i = start; i < this.length; i++) {
        if (el === this[i] && res < i) {
          res = i
        }
      }
      if (start > 0) {
        for (let i = 0; i < this.length - start; i++) {
          if (el === this[i] && res < i) {
            res = i
          }
        }
      }
      return res
    }
    

    map()

    通过指定函数处理数组的每个元素,并返回处理后的数组。

    例子?

    var numbers = [4, 9, 16, 25];
    
    numbers.map(Math.sqrt); // [2,3,4,5]
    

    实现

    Array.prototype.map2 = function (fn, context = null) {
      const res = []
      if (!context) {
        context = this
      }
      for (let i = 0; i < context.length; i++) {
        res.push(fn(context[i], i, context))
      }
      return res
    }
    

    pop()

    删除数组的最后一个元素并返回删除的元素。

    例子?

    let a = [1,2,3]
    a.pop() // 3,a:[1,2]
    

    实现

    Array.prototype.pop2 = function () {
      const res = this[this.length - 1]
      this.length -= 1
      return res
    }
    

    push()

    向数组的末尾添加一个或更多元素,并返回新的长度。

    例子?

    let a = []
    a.push(1,2,3,4) // 4,a:[1,2,3,4]
    

    实现

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

    reduce()

    将数组元素计算为一个值(从左到右)。

    例子?

    let a = [1,2,3,4]
    function getSum(total, num) {
        return total + num;
    }
    a.reduce(getSum) // 10
    

    实现

    Array.prototype.reduce2 = function (fn) {
      let res = this[0]
      for (let i = 1; i < this.length; i++) {
        res = fn(res, this[i], i, this)
      }
      return res
    }
    

    reduceRight()

    将数组元素计算为一个值(从右到左)。

    例子?

    let a = [1,2,3,4]
    function getSum(total, num) {
        return total + num;
    }
    a.reduceRight(getSum) // 10
    

    实现

    Array.prototype.reduceRight2 = function (fn) {
      let res = this[this.length - 1]
      for (let i = this.length - 2; i >= 0; i--) {
        res = fn(res, this[i], i, this)
      }
      return res
    }
    

    reverse()

    反转数组的元素顺序。

    例子?

    var fruits = ["Banana", "Orange", "Apple", "Mango"];
    fruits.reverse();//["Mango", "Apple", "Orange", "Banana"]
    

    实现

    Array.prototype.reverse2 = function () {
      let start = 0
      let end = this.length - 1
      while (start <= Math.floor(this.length / 2)) {
        const temp = this[start]
        this[start] = this[end]
        this[end] = temp
        start++
        end--
      }
      return this
    }
    

    shift()

    删除并返回数组的第一个元素。

    例子?

    var fruits = ["Banana", "Orange", "Apple", "Mango"];
    fruits.shift() // "Banana"
    

    实现

    Array.prototype.shift2 = function () {
      const res = this[0]
      for (let i = 0; i < this.length; i++) {
        if (this[i + 1]) {
          this[i] = this[i + 1]
        }
      }
      this.length -= 1
      return res
    }
    
    

    slice()

    选取数组的一部分,并返回一个新数组。

    例子?

    let a = [1,2,3,4,5]
    a.slice(1,2) // [2]
    

    实现

    Array.prototype.slice2 = function (start, end) {
      if (!end || end > this.length) {
        end = this.length
      }
      if (!start) {
        start = 0
      }
      let res = []
      for (let i = start; i < end; i++) {
        res.push(this[i])
      }
      return res
    }
    

    some()

    检测数组元素中是否有元素符合指定条件。

    例子?

    let a = [1,2,3,8]
    a.some(function (item) {
        return item >= 8
    }) // true
    

    实现

    Array.prototype.some2 = function (fn, context) {
      if (!context) {
        context = this
      }
      for (let i = 0; i < context.length; i++) {
        const res = fn(context[i], i, context)
        if (res === true) {
          return res
        }
      }
      return false
    }
    
    

    sort()

    对数组的元素进行排序。

    例子?

    var points = [40,100,1,5,25,10];
    points.sort(function(a,b){return b-a}); // [100,40,25,10,5,1]
    

    实现

    Array.prototype.sort2 = function (fn) {
      const res = quickSort([...this], fn)
      for (let i = 0; i < res.length; i++) {
        this[i] = res[i]
      }
      return res
    }
    
    const quickSort = function(arr, fn) {
      if (arr.length <= 1) { return arr; }
      const pivotIndex = Math.floor(arr.length / 2);
      const pivot = arr.splice(pivotIndex, 1)[0];
      const left = [];
      const right = [];
      for (let i = 0; i < arr.length; i++){
        if (fn(arr[i], pivot) < 0) {
          left.push(arr[i]);
        } else {
          right.push(arr[i]);
        }
      }
      return quickSort(left, fn).concat([pivot], quickSort(right, fn));
    };
    

    splice()

    从数组中添加或删除元素,返回删除的元素,会改变原数组。

    例子?

    let a = [1,2,6,4,5]
    a.splice(2, 1, 3) // [6] a:[1,2,3,4,5,6]
    

    实现

    Array.prototype.splice2 = function (targetIndex, num, ...el) {
      let k = num
      const res = []
      if (el.length <= 0) {
        for (let i = targetIndex; i < this.length; i++) {
          if (this[i + num]) {
            res.push(this[i])
            this[i] = this[i + num]
          }
        }
        this.length -= num
      } else {
        let temp = []
        for (let i = targetIndex; i < this.length; i++) {
          if (res.length < num) {
            res.push(this[i])
          } else {
            temp.push(this[i])
          }
        }
        this.length = this.length - (temp.length + num)
        let len = this.length + el.length
        let j = 0
        for (let i = targetIndex; i < len; i++) {
          this[i] = el[j]
          j++
        }
        j = 0
        len = this.length + temp.length
        for (let i = this.length; i < len; i++) {
          this[i] = temp[j]
          j++
        }
      }
      return res
    }
    

    toString()

    把数组转换为字符串,并返回结果(会递归转换)。

    例子?

    let a = [
        [1, {a:1}],
        [2,3]
    ]
    a.toString() // "1,[object Object],2,3"
    

    实现

    Array.prototype.toString2 = function () {
      return toStrng(this)
    }
    
    function toStrng (arr) {
      if (Array.isArray(arr)) {
        let res
        for (let i = 0; i < arr.length; i++) {
          if (!res) {
            res = toStrng(arr[i])
          } else {
            res += ',' + toStrng(arr[i])
          }
        }
        return res
      } else if (typeof arr === 'number' || typeof arr === 'string') {
        return arr
      } else {
        return Object.prototype.toString.call(arr)
      }
    }
    

    unshift()

    向数组的开头添加一个或更多元素,并返回新的长度。

    例子?

    let a = [3,4,5]
    a.unshift(1,2) //5 a:[1,2,3,4,5]
    

    实现

    Array.prototype.unshift2 = function (...arr) {
      const temp = []
      for (let i = 0; i < this.length; i++) {
        temp.push(this[i])
      }
      this.length = arr.length
      for (let i = 0; i < this.length; i++) {
        this[i] = arr[i]
      }
      const len = this.length + temp.length
      let j = 0
      for (let i = arr.length; i < len; i++) {
        this[i] = temp[j]
        j++
      }
      return len
    }
    

    最后

    用了两大篇文章终于是把几乎所有方法都写完了,历时三个月哈哈,中间懒了两个月。写完之后收获不小,特别是在项目中用到的时候,不再需要再翻文档找到使用方法和注意事项了,直接就是用!

    说实话从头理到尾并没有说增长了什么新知识,然后自己实现的方法也没有说多么完善多么好,但是写完之后不管是面试官问还是自己用都会变得信手拈来。到此结束了。

    第一篇在这里js数组所有内置方法简述以及手动实现(一)。

    所有源码在GITHUB,欢迎Star。

    如果有什么不足或错误的地方,欢迎读者评论和留言

    当然,要是本文对你有所帮助,欢迎点赞和转发,谢谢?


    下载网 » js数组所有内置方法简述以及手动实现(二)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元