利用原生JS实现数组原型方法

1. 判断对象数据类型

初始代码:

const isType = function (type) {
    return function (t) {
        return `[object ${type}]` === Object.prototype.toString.call(t)
    }
}
const isArray = isType('Array')
console.log(isArray([]))

简化后:

const isType = type => t => `[object ${type}]` === Object.prototype.toString.call(t)
const isArray = isType('Array')
// 此时 isArray 为
// isArray = t => `[object Array]` === Object.prototype.toString.call(t)

原理:
  Object 的原型上有 toString 方法,可以返回对象的数据类型;
  例:传入 [1, 2, 3] 调用后得 [object Array] 字符串;传入 { name: ‘aaa’ } 调用后得 [object Object] 字符串。

注意:

  • 为什么要用 call()
      首先要解释原型链,当对象实例调用方法时,如果找不到该方法的声明,会按照原型链一次向上找,直到找到最近的一个声明。如果直接使用数组实例(以数组为例): [1, 2, 3].prototype.toString 或 [1, 2, 3].toString,此时会根据原型链向上寻找,然而在 Object 对象上也有一个 toString 方法(强制类型转换为字符),此时会优先执行这个方法,所以不会达到目的,所以需要跳过原型链直接去执行 Object 原型上的 toString
      call() 方法的作用是执行一个方法,并改变这个方法的 this 指向,所以利用 Object.prototype.toString.call(t) 强制执行 Object.prototype.toString 并且把 this 指向 参数t
  • isType(‘Array’) 在传入参数时,首字母必须大写

扩展:

  1. call()apply()bind() 方法都可以改变原方法的 this 指向;
  2. call() 方法参数是 (this指向, 原方法所需参数1, 原方法所需参数2 ) ,会直接调用函数;
  3. apply() 方法参数是 (this指向, [ 原方法所需参数1, 原方法所需参数2 ]) ,会直接调用函数;
  4. bind() 方法参数是 (this指向, 原方法所需参数1, 原方法所需参数2 ) ,会返回一个新函数。

  

2. 利用原生JS实现map方法

  • 什么是map()方法?
      数组调用 map() 方法后会返回一个满足条件的新数组.第一个参数是需要循环执行的回调函数(必须),第二个参数是回调函数中的 this 指向。

    • 回调函数有三个参数:item,index,arr
    1. item:当前数组项,
    2. index:当前数组索引,
    3. arr:当前数组
    • 当第二个参数为空、传入 nullundefined 时,会默认指向 window
        

    注意:当使用 ES6 箭头函数时,第二个参数会因为箭头函数的词法绑定而失效

    例:

const arr = [1, 2, 3, 4]
window.number = 1
let obj = {number: 2}

// 第二个参数不传
let arr1 = arr.map(function (item, index, arr) {
    // return item * number  // 此时 number 为 window.number
    return item * this.number  // 此时 number 也为 window.number
})
console.log(arr1)  // [1, 2, 3, 4]

// 第二个参数传入obj
let arr2 = arr.map(function (item, index, arr) {
    // return item * number  // 此时 number 为 window.number,可知不使用this不会改变指向
    return item * this.number  // 此时 number 变为 obj.number
}, obj)
console.log(arr2)  // [2, 4, 6, 8]

// 使用箭头函数
let arr3 = arr.map((item, index, arr) => {
    return item * this.number  // 此时 number 为 window.number,第二个参数失效
}, obj)
console.log(arr3)  // [1, 2, 3, 4]
  • 利用原生JS实现 map()
Array.prototype.myMap = function (fn, pointer) {
    let newArr = []
    for (let i = 0; i < this.length; i++) {
        newArr.push(fn.call(pointer, this[i], i, this))
    }
    return newArr
}

  

3. 利用原生JS实现filter方法

  • 什么是filter()方法?
      数组的filter()方法是过滤器,对数组中的每一项通过回调函数进行筛选,返回一个每项都满足条件的新数组。第一个参数是需要循环执行的回调函数(必须),第二个参数是回调函数中的 this 指向。

    • 回调函数有三个参数:item,index,arr
    1. item:当前数组项,
    2. index:当前数组索引,
    3. arr:当前数组
    • 当第二个参数为空、传入 nullundefined 时,会默认指向 window
        

    注意:

    1. 当使用 ES6 箭头函数时,第二个参数会因为箭头函数的词法绑定而失效
    2. filter()方法不会检测空数组
    3. filter()方法不会改变原数组
  • 利用原生JS实现 filter()

Array.prototype.myFilter = function (fn, pointer) {
    let newArr = []
    for (let i = 0; i < this.length; i++) {
        fn.call(pointer, this[i], i, this) ? newArr.push(this[i]) : false
        // fn.call(pointer, this[i], i, this) ? newArr.push(this[i]) : continue
        // continue 处报错,三元表达式内不能使用语句
    }
    return newArr
}

  

4. 利用原生JS实现some方法

  • 什么是some()方法?
      数组的some()方法对数组中的每一项通过回调函数进行筛选,返回一个Boolean类型值,当有一个值都满足条件,返回 true,剩余值不检测,否则返回 false。第一个参数是需要循环执行的回调函数(必须),第二个参数是回调函数中的 this 指向。

    • 回调函数有三个参数:item,index,arr
    1. item:当前数组项,
    2. index:当前数组索引,
    3. arr:当前数组
    • 当第二个参数为空、传入 nullundefined 时,会默认指向 window
        

    注意:

    1. 当使用 ES6 箭头函数时,第二个参数会因为箭头函数的词法绑定而失效
    2. 当数组为空时,返回false
  • 利用原生JS实现 some()

Array.prototype.mySome = function (fn, pointer) {
    let isTrue = false
    for (let i = 0; i < this.length; i++) {
        if (fn.call(pointer, this[i], i, this)) {
            isTrue = true
            break
        }
    }
    return isTrue
}

问题参考链接:

https://blog.csdn.net/VhWfR2u02Q/article/details/91350072

(本文会持续更新)

以上是本人对于上述链接中提到的某些问题的个人理解,仅供参考,如有错误,还望大神指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值