Array.prototype.filter()的理解和手写

1. 简单解释一下Array.prototype.filter()

Array.prototype.filter() 是 JavaScript 数组对象的一个方法,用于创建一个新数组,其中包含通过给定函数测试的所有元素。它接受一个回调函数作为参数,该函数用于测试每个数组元素,并返回一个新数组,其中包含满足测试条件的元素。
下面是 filter() 方法的详细说明:

  1. 语法
    const newArray = array.filter(callback(element, index, array), thisArg);
    
    • callback:用于测试每个元素的函数,它可以接受三个参数:
      • element:当前正在处理的元素。
      • index(可选):当前正在处理的元素的索引。
      • array(可选):调用 filter 方法的数组。
    • thisArg(可选):执行回调函数时使用的 this 值。
  2. 返回值
    • 返回一个新数组,其中包含满足条件的所有元素。如果没有满足条件的元素,则返回空数组。
  3. 回调函数
    • 回调函数是 filter 方法的核心。它用于定义过滤条件。如果回调函数返回 true,则当前元素会被添加到新数组中;如果返回 false,则不会添加。
  4. 示例
    const numbers = [1, 2, 3, 4, 5];
    // 过滤出所有偶数
    const evenNumbers = numbers.filter(num => num % 2 === 0);
    // evenNumbers: [2, 4]
    // 过滤出所有大于2的数
    const greaterThanTwo = numbers.filter(num => num > 2);
    // greaterThanTwo: [3, 4, 5]
    
    在第一个示例中,我们使用 filter() 方法过滤出了数组 numbers 中的所有偶数。在第二个示例中,我们过滤出了所有大于2的数。
  5. 注意事项
    • filter() 方法不会改变原始数组,它总是返回一个新数组。
    • 如果没有传入回调函数,则 filter() 方法会返回原始数组的一个浅拷贝。
    • 如果需要更改原始数组,可以使用 forEach()map()reduce() 方法。
      通过理解 filter() 方法的工作原理和用法,你可以方便地对数组进行筛选操作,并得到满足特定条件的元素组成的新数组。

2.参数thisArg的理解和作用

Array.prototype.filter() 方法中,thisArg 参数用于指定在执行回调函数时使用的 this 值。虽然在大多数情况下,我们不需要显式地指定 this 值,但在某些情况下,它可以提供额外的灵活性和控制。
主要的作用和使用场景包括:

  1. 指定上下文
    • 当回调函数需要访问外部对象的属性或方法时,可以使用 thisArg 参数来指定回调函数中 this 的上下文,确保在回调函数中可以正确访问外部对象。
  2. 在对象方法中使用
    • filter() 方法被调用时,如果回调函数是一个对象的方法,而该方法中使用了 this 关键字来引用对象的属性或方法,那么必须通过 thisArg 参数来指定该对象,以确保 this 关键字引用的是正确的对象。
  3. 增强可读性和维护性
    • 通过显式地指定 thisArg 参数,可以使代码更加清晰易懂,并提高代码的可维护性。它可以明确表明回调函数中 this 的含义和作用域。
      举例来说,假设我们有一个对象 person,包含一个 friends 数组,我们想要筛选出所有年龄大于等于 18 的朋友。这种情况下,可以使用 thisArg 参数来指定回调函数中的 this 值为 person 对象,以确保在回调函数中可以访问 person 对象的属性。
const person = {
    name: 'Alice',
    age: 25,
    friends: [
        { name: 'Bob', age: 20 },
        { name: 'Charlie', age: 30 },
        { name: 'David', age: 18 }
    ],
    adultFriends: function(friend) {
        return friend.age >= this.age;
    }
};
const adultFriends = person.friends.filter(person.adultFriends, person);
// adultFriends: [{ name: 'Charlie', age: 30 }]

在这个示例中,filter() 方法的回调函数 person.adultFriends 中使用了 this 关键字来引用 person 对象的 age 属性。通过在 filter() 方法中指定 thisArg 参数为 person,确保了在回调函数中可以正确地访问 person 对象的属性。

3.手写Array.prototype.filter()代码

 Array.prototype._filter = function (callback, thisArg) {
            if (typeof callback !== "function") {
                throw Error('参数必须是一个函数')
            }
            //定义一个返回结果的数组
            const filteredArray = []
            const thisContext = thisArg || globalThis
            
            //遍历数组的每一个元素
            for (let i = 0; i < this.length; i++) {
                //使用call方法将this绑定到thisContext上,并传入当前元素和索引
                if (callback.call(thisContext,this[i],i,this)){
                    //如果回调函数返回true,将当前元素添加到结果数组中
                    filteredArray.push(this[i])

                }
           }
           return filteredArray
        }
        const nums=[1,2,3,4,5,6,7,8]
        const filterNum=nums._filter(num => num>5)
        console.log(filterNum);

4.解释一下call方法

在JavaScript中,call 方法是 Function 对象的一个方法,允许你调用一个函数,并指定这个函数内部的 this 值以及参数列表。这意味着你可以控制函数执行时的上下文(即函数中的 this 指向的对象),同时也可以向该函数传递参数。
call 方法的语法如下:

function.call(thisArg, arg1, arg2, ...)
  • function:这是你想要调用的函数。
  • thisArg:可选的参数,当调用函数时,会被用作 this 的值。如果不传或者传 nullundefined,在非严格模式下 this 指向全局对象,在严格模式下 this 指向 undefined
  • arg1, arg2, ...:要传递给函数的参数列表。
    下面是一个使用 call 方法的例子:
function greet(greeting, name) {
  console.log(greeting + ', ' + name + '!');
}
// 使用 call 方法调用 greet 函数
greet.call(null, 'Hello', 'Alice'); // 输出:Hello, Alice!

在上面的例子中,greet 函数被调用,并通过 call 方法传递了参数。thisArg(在这个例子中是 null)没有实际作用,因为 greet 函数并没有使用 this
call 方法的一个常见用途是在一个对象的方法被另一个对象借用时。例如:

const person1 = {
  name: 'Alice',
  greet: function() {
    console.log(`Hello, my name is ${this.name}`);
  }
};
const person2 = {
  name: 'Bob'
};
// 使用 call 方法,以 person2 的上下文来调用 person1 的 greet 方法
person1.greet.call(person2); // 输出:Hello, my name is Bob

在这个例子中,尽管 greet 方法是 person1 的方法,但通过使用 call 方法,我们以 person2 的上下文来调用了它,因此输出中使用了 person2name 属性。

  • 8
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值