Javascript数组研究03_手写实现_fill_filter_find_findIndex_findLast_findLastIndex
6 Array.fill()
6.1 基本介绍
fill()
方法用一个固定值填充一个数组中从起始索引(默认为 0)到终止索引(默认为 array.length
)内的全部元素。它返回修改后的数组。
fill(value)
fill(value, start)
fill(value, start, end)
输入参数:
value
:用来填充数组元素的值。start
(可选):开始填充的位置,默认值为 0,索引处理方法和copyWithin一致。end
(可选):停止填充的位置(不包含该位置),默认值为this.length
,索引处理方法和copyWithin方法一致。
输出:修改后的原数组。
注意事项:
- 该方法会改变原数组,是修改方法。
- 对于稀疏数组,空槽也会被
value
填充。 - 是通用的方法
- 在空数组上不会有任何处理
- 如果value值为对象的时候,会使填充的所有内容都是执行同一对象
6.2 手写实现
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)
难点总结:
- 处理索引:
start
和end
可以使用统一的方法处理索引,然后进行边界判断。 - 正确判断NaN:当
start
和end
为NaN时需要重新处理为默认值
7 Array.filter()
7.1 基本介绍
filter()
方法创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素。语法如下:
filter(callbackFn)
filter(callbackFn, thisArg)
输入参数:
callbackFn(element, index, array)
:用于测试每个元素的函数,返回true
保留元素,返回false
不保留。thisArg
(可选):执行callbackFn
时使用的this
值。
输出:一个新的数组,包含通过测试的元素。
注意事项:
filter()
不会改变原数组,他是一个复制方法。- 对于稀疏数组,
callbackFn
不会针对空槽调用,空槽也不会出现在新数组中。 - 如果
callbackFn
改变了数组,则会影响后续的遍历。
7.2 手写实现
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
。语法如下:
find(callbackFn)
find(callbackFn, thisArg)
输入参数:
callbackFn(element, index, array)
:用于测试每个元素的函数。thisArg
(可选):执行callbackFn
时使用的this
值。
输出:满足测试函数的第一个元素的值,或 undefined
。
注意事项:
- 一旦找到满足条件的元素,方法立即返回,不会继续遍历。
- 对于稀疏数组,空槽的行为和
undefined
表现一致。 - 如果在遍历过程中修改了数组,可能会影响结果。
find
方法是通用的
8.2 手写实现
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
。语法如下:
findIndex(callbackFn)
findIndex(callbackFn, thisArg)
输入参数:
callbackFn(element, index, array)
:用于测试每个元素的函数。thisArg
(可选):执行callbackFn
时使用的this
值。
输出:满足测试函数的第一个元素的索引,或 -1
。
注意事项:
- 一旦找到满足条件的元素,方法立即返回索引,不会继续遍历。
- 对于稀疏数组,空槽行为和
undefined
一致。 - 数组在遍历过程中被修改,可能会影响结果。
-** 通用的**方法
9.2 手写实现
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
。语法如下:
findLast(callbackFn)
findLast(callbackFn, thisArg)
输入参数:
callbackFn(element, index, array)
:用于测试每个元素的函数。thisArg
(可选):执行callbackFn
时使用的this
值。
输出:满足测试函数的第一个元素的值(从后向前),或 undefined
。
注意事项:
- 从数组的末尾开始遍历。
- 对于稀疏数组,空槽行为和
undefined
一致。 - 如果在遍历过程中修改了数组,可能会影响结果。
10.2 手写实现
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;
};
难点总结:
- 处理空槽:
findLast
和findIndex
以及find
处理空槽的行为一致。
11 Array.findLastIndex()
11.1 基本介绍
findLastIndex()
方法从数组末尾开始遍历,返回第一个满足提供的测试函数的元素的索引。否则返回 -1
。语法如下:
findLastIndex(callbackFn)
findLastIndex(callbackFn, thisArg)
输入参数:
callbackFn(element, index, array)
:用于测试每个元素的函数。thisArg
(可选):执行callbackFn
时使用的this
值。
输出:满足测试函数的第一个元素的索引(从后向前),或 -1
。
注意事项:
- 从数组的末尾开始遍历。
- 对于稀疏数组,空槽行为和
undefined
一致。。 - 数组在遍历过程中被修改,可能会影响结果。
- 该方法是通用方法
11.2 手写实现
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;
};
难点总结:
- 处理空槽:
find
和findLast
和findIndex
和findLastIndex
处理行为一致,都是把空槽当作undefined处理。