手写实现 Array.prototype.every 方法
实现数组的 every 方法,用于检测数组所有元素是否都满足指定条件
问题
Array.prototype.every() 方法用于测试数组中的所有元素是否都能通过指定函数的测试。它返回一个布尔值,只有当数组中的每个元素都满足条件时才返回 true,否则返回 false。
需要实现一个自定义的 every 方法,模拟原生 every 方法的行为。
解答
/**
* 实现 Array.prototype.every 方法
* @param {Function} callback - 测试函数,接收三个参数:当前元素、索引、原数组
* @param {*} thisArg - 执行 callback 时使用的 this 值
* @returns {Boolean} - 所有元素都通过测试返回 true,否则返回 false
*/
Array.prototype.myEvery = function(callback, thisArg) {
// 边界条件判断
if (this == null) {
throw new TypeError('Array.prototype.myEvery called on null or undefined');
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
// 将调用对象转换为对象
const O = Object(this);
// 获取数组长度
const len = O.length >>> 0;
// 遍历数组
for (let i = 0; i < len; i++) {
// 只检查数组中实际存在的元素(跳过空位)
if (i in O) {
// 调用回调函数,如果返回 false,立即返回 false
if (!callback.call(thisArg, O[i], i, O)) {
return false;
}
}
}
// 所有元素都通过测试,返回 true
return true;
};
使用示例
// 示例1:检查所有元素是否都大于 0
const arr1 = [1, 2, 3, 4, 5];
console.log(arr1.myEvery(item => item > 0)); // true
console.log(arr1.myEvery(item => item > 3)); // false
// 示例2:检查所有元素是否都是偶数
const arr2 = [2, 4, 6, 8];
console.log(arr2.myEvery(num => num % 2 === 0)); // true
// 示例3:使用索引参数
const arr3 = [10, 20, 30, 40];
console.log(arr3.myEvery((item, index) => item === (index + 1) * 10)); // true
// 示例4:使用 thisArg 参数
const threshold = {
min: 5,
max: 50
};
const arr4 = [10, 20, 30];
console.log(arr4.myEvery(function(item) {
return item >= this.min && item <= this.max;
}, threshold)); // true
// 示例5:空数组返回 true(符合原生行为)
const arr5 = [];
console.log(arr5.myEvery(item => item > 100)); // true
// 示例6:稀疏数组(跳过空位)
const arr6 = [1, , 3, , 5];
console.log(arr6.myEvery(item => item > 0)); // true
关键点
- 类型检查:需要检查
this是否为null/undefined,以及callback是否为函数 - 长度处理:使用
>>> 0确保长度为非负整数 - 短路逻辑:一旦发现不满足条件的元素,立即返回
false,无需继续遍历 - 稀疏数组处理:使用
in操作符检查属性是否存在,跳过数组空位 - this 绑定:使用
call方法正确绑定thisArg到回调函数 - 空数组特性:空数组调用
every返回true(逻辑学中的”空真”原则) - 不修改原数组:
every方法不会改变原数组的内容 - 返回布尔值:使用
!运算符将回调函数的返回值转换为布尔值进行判断
目录