Javascript数组研究03_手写实现_fill_filter_find_findIndex_findLast_findLastIndex

6 Array.fill()

6.1 基本介绍

fill() 方法用一个固定值填充一个数组中从起始索引(默认为 0)到终止索引(默认为 array.length)内的全部元素。它返回修改后的数组。

javascript 复制代码
fill(value)
fill(value, start)
fill(value, start, end)

输入参数

  • value:用来填充数组元素的值。
  • start(可选):开始填充的位置,默认值为 0,索引处理方法和copyWithin一致。
  • end(可选):停止填充的位置(不包含该位置),默认值为 this.length,索引处理方法和copyWithin方法一致。

输出:修改后的原数组。

注意事项

  • 该方法会改变原数组,是修改方法
  • 对于稀疏数组,空槽也会被value填充。
  • 通用的方法
  • 在空数组上不会有任何处理
  • 如果value值为对象的时候,会使填充的所有内容都是执行同一对象
6.2 手写实现
javascript 复制代码
MyArray.prototype.fill = function(value, start = 0, end = this.length) {
    const length = this.length;

    // 转换为整数
    let relativeStart = Number(start);
    let relativeEnd = Number(end);

    // 处理 NaN
    if (isNaN(relativeStart)) relativeStart = 0;
    if (isNaN(relativeEnd)) relativeEnd = length;

    // 转换为整数,向零方向取整
    let to = relativeEnd < 0 ? Math.max(length + relativeEnd, 0) : Math.min(relativeEnd, length);
    let from = relativeStart < 0 ? Math.max(length + relativeStart, 0) : Math.min(relativeStart, length);

    if (from >= length || to <= from) return this;

    for (let i = from; i < to; i++) {
        this[i] = value;
    }

    return this;
};


let arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4)); // [4, 4, 4]
arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4, 1)); // [1, 4, 4]
arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4, 1, 2)); // [1, 4, 3]
arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4, 1, 1)); // [1, 2, 3]
arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4, 3, 3)); // [1, 2, 3]
arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4, -3, -2)); // [4, 2, 3]
arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4, NaN, NaN)); // [1, 2, 3]
arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4, 3, 5)); // [1, 2, 3]
arr_1 = new MyArray(1, 2, 3)
console.log(new MyArray(3).fill(4)); // [4, 4, 4]

// 一个简单的对象,被数组的每个空槽所引用
const arr = new MyArray(3).fill({}); // [{}, {}, {}]
arr[0].hi = "hi"; // [{ hi: "hi" }, { hi: "hi" }, { hi: "hi" }]
console.log(arr)

难点总结

  • 处理索引startend 可以使用统一的方法处理索引,然后进行边界判断。
  • 正确判断NaN :当startend为NaN时需要重新处理为默认值

7 Array.filter()

7.1 基本介绍

filter() 方法创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素。语法如下:

javascript 复制代码
filter(callbackFn)
filter(callbackFn, thisArg)

输入参数

  • callbackFn(element, index, array):用于测试每个元素的函数,返回 true 保留元素,返回 false 不保留。
  • thisArg(可选):执行 callbackFn 时使用的 this 值。

输出:一个新的数组,包含通过测试的元素。

注意事项

  • filter() 不会改变原数组,他是一个复制方法
  • 对于稀疏数组,callbackFn 不会针对空槽调用,空槽也不会出现在新数组中。
  • 如果 callbackFn 改变了数组,则会影响后续的遍历。
7.2 手写实现
javascript 复制代码
MyArray.prototype.filter = function(callFn, thisArg){
    if(typeof callFn !== "function"){
        throw new TypeError(callFn + "is not a callback function")
    }
    let res;
    if(Array.isArray(this)){
        const C = getConstructor(this)
        res = new C()
    }else{
        res = new Array()
    }
    

    for(let i = 0; i < this.length; i ++){
        if(!(i in this)) continue
        if(callFn.call(thisArg, this[i], i, this)){
            res.push(this[i])
        }
    }

    return res
}

function isBigEnough(value) {
    return value >= 10;
}

const arr_2 = new MyArray(12, 5, 8, 130, 44)
const filtered = arr_2.filter(isBigEnough);
console.log(filtered)
// filtered is [12, 130, 44]

console.log(MyArray.prototype.filter.call([1, , undefined], (x) => x === undefined)); // [undefined]

const arrayLike = {
    length: 3,
    0: "a",
    1: "b",
    2: "c",
  };
  console.log(MyArray.prototype.filter.call(arrayLike, (x) => x <= "b"));
  // [ 'a', 'b' ]
  

难点总结

  • 处理空槽 :使用 in 操作符检查索引是否存在,跳过空槽。
  • 创建新数组:如何获取正确的对应的构造函数从而返回一致的类型的实例对象是个难点。

8 Array.find()

8.1 基本介绍

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

javascript 复制代码
find(callbackFn)
find(callbackFn, thisArg)

输入参数

  • callbackFn(element, index, array):用于测试每个元素的函数。
  • thisArg(可选):执行 callbackFn 时使用的 this 值。

输出 :满足测试函数的第一个元素的值,或 undefined

注意事项

  • 一旦找到满足条件的元素,方法立即返回,不会继续遍历。
  • 对于稀疏数组,空槽的行为和undefined表现一致
  • 如果在遍历过程中修改了数组,可能会影响结果。
  • find方法是通用的
8.2 手写实现
javascript 复制代码
  MyArray.prototype.find = function(callFn, thisArg){
    if(typeof callFn !== "function"){
        throw new TypeError(callFn + "is not a function")
    }

    for(let i = 0; i < this.length; i++){
        if(callFn.call(thisArg, this[i], i, this)) return this[i]
    }

    return undefined
  }

  const inventory = new MyArray(
    { name: "apples", quantity: 2 },
    { name: "bananas", quantity: 0 },
    { name: "cherries", quantity: 5 },
  )
  const result = inventory.find(({ name }) => name === "cherries");
  console.log(result); // { name: 'cherries', quantity: 5 }

  const arrayLike_2 = {
    length: 3,
    0: 2,
    1: 7.3,
    2: 4,
  };
  console.log(MyArray.prototype.find.call(arrayLike_2, (x) => !Number.isInteger(x)));
  // 7.3

难点总结

  • 提前终止遍历:找到满足条件的元素后立即返回。
  • 处理空槽:和已经学习过的every、filter行为有差异,会对空槽执行回调函数,空槽被视为undefined

9 Array.findIndex()

9.1 基本介绍

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

javascript 复制代码
findIndex(callbackFn)
findIndex(callbackFn, thisArg)

输入参数

  • callbackFn(element, index, array):用于测试每个元素的函数。
  • thisArg(可选):执行 callbackFn 时使用的 this 值。

输出 :满足测试函数的第一个元素的索引,或 -1

注意事项

  • 一旦找到满足条件的元素,方法立即返回索引,不会继续遍历。
  • 对于稀疏数组,空槽行为和undefined一致
  • 数组在遍历过程中被修改,可能会影响结果。
    -** 通用的**方法
9.2 手写实现
javascript 复制代码
MyArray.prototype.findIndex = function(callbackFn, thisArg) {
    if (typeof callbackFn !== "function") {
        throw new TypeError(callbackFn + ' is not a function');
    }

    for (let i = 0; i < this.length; i++) {
        if (callbackFn.call(thisArg, this[i], i, this)) {
            return i;
        }
    }
    return -1;
};


console.log(MyArray.prototype.findIndex.call([1, , 3],(x) => x === undefined)) // 1
const arrayLike_3 = {
    length: 3,
    0: 2,
    1: 7.3,
    2: 4,
  };
  console.log(
    MyArray.prototype.findIndex.call(arrayLike_3, (x) => !Number.isInteger(x)),
  ); // 1

难点总结

  • 返回索引 :与 find() 方法不同,findIndex() 返回索引。
  • 处理空槽:find和findIndex处理空槽行为一致,都会视为undefined进行处理。

10 Array.findLast()

10.1 基本介绍

findLast() 方法从数组末尾开始遍历,返回第一个满足提供的测试函数的元素的值。否则返回 undefined。语法如下:

javascript 复制代码
findLast(callbackFn)
findLast(callbackFn, thisArg)

输入参数

  • callbackFn(element, index, array):用于测试每个元素的函数。
  • thisArg(可选):执行 callbackFn 时使用的 this 值。

输出 :满足测试函数的第一个元素的值(从后向前),或 undefined

注意事项

  • 从数组的末尾开始遍历。
  • 对于稀疏数组,空槽行为和undefined一致
  • 如果在遍历过程中修改了数组,可能会影响结果。
10.2 手写实现
javascript 复制代码
MyArray.prototype.findLast = function(callbackFn, thisArg) {
    if (typeof callbackFn !== "function") {
        throw new TypeError(callbackFn + ' is not a function');
    }

    for (let i = this.length - 1; i >= 0; i--) {
        let element = this[i];
        if (callbackFn.call(thisArg, element, i, this)) {
            return element;
        }
    }

    return undefined;
};

难点总结

  • 处理空槽findLastfindIndex以及find处理空槽的行为一致。

11 Array.findLastIndex()

11.1 基本介绍

findLastIndex() 方法从数组末尾开始遍历,返回第一个满足提供的测试函数的元素的索引。否则返回 -1。语法如下:

javascript 复制代码
findLastIndex(callbackFn)
findLastIndex(callbackFn, thisArg)

输入参数

  • callbackFn(element, index, array):用于测试每个元素的函数。
  • thisArg(可选):执行 callbackFn 时使用的 this 值。

输出 :满足测试函数的第一个元素的索引(从后向前),或 -1

注意事项

  • 从数组的末尾开始遍历。
  • 对于稀疏数组,空槽行为和undefined一致。。
  • 数组在遍历过程中被修改,可能会影响结果。
  • 该方法是通用方法
11.2 手写实现
javascript 复制代码
MyArray.prototype.findLastIndex = function(callbackFn, thisArg) {
    if (typeof callbackFn !== "function") {
        throw new TypeError(callbackFn + ' is not a function');
    }

    for (let i = this.length - 1; i >= 0; i--) {
        if (callbackFn.call(thisArg, this[i], i, this)) {
            return i;
        }
    }

    return -1;
};

难点总结

  • 处理空槽findfindLastfindIndexfindLastIndex处理行为一致,都是把空槽当作undefined处理。
相关推荐
腾讯TNTWeb前端团队5 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰9 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪9 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy10 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom10 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom10 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom10 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom11 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试