Array对象的方法实现(4)----Array.prototype.findIndex和Array.prototype.forEach(实现常规参数的功能)
8,Array的findIndex方法
findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
语法:arr.findIndex(callback[, thisArg])
注意:1,有返回值(找到的第一个元素下标或者没找到的-1)。2,不改变原数组
Array.prototype._findIndex = function(fn/*,thisArg*/){
if(this === null) throw new TypeError('this is null or not defined');
if(typeof fn !== 'function') throw new TypeError('fn must be a function');
let that = Object(this),len = this.length >>> 0,thisArg = arguments[1];
for(let i = 0;i < len;i++){
if(fn.call(thisArg,that[i],i,that)) return i;
}
return -1;
}
mozilla:
Array.prototype.findIndex = function(predicate) {
if (this === null) {
throw new TypeError('Array.prototype.findIndex called on null or undefined');
}
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
var list = Object(this);
var length = list.length >>> 0;
var thisArg = arguments[1];
var value;
for (var i = 0; i < length; i++) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) {
return i;
}
}
return -1;
};
测试1:返回数组中第一个大于15的数的index
function isBigEnough(element,index,array) {
return element >= 15;
}
console.log([12, 5, 8, 130, 44].findIndex(isBigEnough,this)); // 3
console.log([12, 5, 8, 130, 44]._findIndex(isBigEnough,this)); // 3
测试2:返回数组中第一个质数的index
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) return false;
}
return (element > 1);
}
console.log( [4, 6, 8, 12].findIndex(isPrime) ); // -1, 没找到质数元素
console.log( [4, 6, 7, 12].findIndex(isPrime) ); // 2
console.log( [4, 6, 8, 12]._findIndex(isPrime) ); // -1, 没找到质数元素
console.log( [4, 6, 7, 12]._findIndex(isPrime) ); // 2
9,Array的forEach方法
forEach() 方法对数组的每个元素执行一次提供的函数。
语法:array.forEach(callback(currentValue, index, array){//do something}, this)
注意:1,是对数组中的每个元素进行操作。2,方法本身不改变原数组
Array.prototype._forEach = function(fn){
if(this === null) throw new TypeError('this is null or not defined');
if(typeof fn !== 'function') throw new TypeError('fn must be a function');
let that =Object(this),len = this.length >>> 0,thisArg = null;
if(arguments[1])thisArg = arguments[1];
for(let i = 0;i < len;i++){
if(i in that) fn.call(thisArg,that[i],i,that);
}
}
注意:此处的判断if( i in that),如果不添加此判断,检测[1,2,,3]在2的位置会输出undefined
mozilla:
Array.prototype.forEach = function(callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError(' this is null or not defined');
}
// 1. Let O be the result of calling toObject() passing the
// |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get() internal
// method of O with the argument "length".
// 3. Let len be toUint32(lenValue).
var len = O.length >>> 0;
// 4. If isCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function');
}
// 5. If thisArg was supplied, let T be thisArg; else let
// T be undefined.
if (arguments.length > 1) {
T = thisArg;
}
// 6. Let k be 0
k = 0;
// 7. Repeat, while k < len
while (k < len) {
var kValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty
// internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal
// method of O with argument Pk.
kValue = O[k];
// ii. Call the Call internal method of callback with T as
// the this value and argument list containing kValue, k, and O.
callback.call(T, kValue, k, O);
}
// d. Increase k by 1.
k++;
}
// 8. return undefined
};
测试1:
let a = ['a', 'b', 'c'],xxx;
a.forEach(function(element) {
console.log(element);
});
a._forEach(function(element) {
console.log(element);
});
//a
//b
//c
测试2:
function logArrayElements(element, index, array) {
console.log("a[" + index + "] = " + element);
}
[2, 5, ,9].forEach(logArrayElements);
[2, 5, ,9]._forEach(logArrayElements);
[2, 5,"" ,9].forEach(logArrayElements);
[2, 5,"" ,9]._forEach(logArrayElements);
[2, 5, undefined ,9].forEach(logArrayElements);
[2, 5, undefined ,9]._forEach(logArrayElements);
[2, 5, xxx ,9].forEach(logArrayElements);
[2, 5, xxx ,9]._forEach(logArrayElements);
输出:
a[0] = 2
a[1] = 5
a[3] = 9
a[0] = 2
a[1] = 5
a[3] = 9
a[0] = 2
a[1] = 5
a[2] =
a[3] = 9
a[0] = 2
a[1] = 5
a[2] =
a[3] = 9
a[0] = 2
a[1] = 5
a[2] = undefined
a[3] = 9
a[0] = 2
a[1] = 5
a[2] = undefined
a[3] = 9
a[0] = 2
a[1] = 5
a[2] = undefined
a[3] = 9
a[0] = 2
a[1] = 5
a[2] = undefined
a[3] = 9
测试3:
function Counter() {
this.sum = 0;
this.count = 0;
}
Counter.prototype.add = function(array) {
array._forEach(function(entry) {
this.sum += entry;
++this.count;
}, this);
//console.log(this);
};
var obj = new Counter();
obj.add([1, 3, 5, 7]);
console.log(obj.count);
// 4 === (1+1+1+1)
console.log(obj.sum);
// 16 === (1+3+5+7)
测试4:
var words = ["one", "two", "three", "four"];
words.forEach(function(word) {
console.log(word);
if (word === "two") {
words.shift();
}
});
//one
//two
//four
console.log(words);
//["two", "three", "four"]
可以看到forEach方法本身是没有改变数组的,而是通过callback来实现改变数组。其实方法本身是没有对数组进行改变。
其他
[我的博客,欢迎交流!](http://rattenking.gitee.io/stone/index.html)
[我的CSDN博客,欢迎交流!](https://blog.csdn.net/m0_38082783)
[微信小程序专栏](https://blog.csdn.net/column/details/18335.html)
[前端笔记专栏](https://blog.csdn.net/column/details/18321.html)
[微信小程序实现部分高德地图功能的DEMO下载](http://download.csdn.net/download/m0_38082783/10244082)
[微信小程序实现MUI的部分效果的DEMO下载](http://download.csdn.net/download/m0_38082783/10196944)
[微信小程序实现MUI的GIT项目地址](https://github.com/Rattenking/WXTUI-DEMO)
[微信小程序实例列表](http://blog.csdn.net/m0_38082783/article/details/78853722)
[前端笔记列表](http://blog.csdn.net/m0_38082783/article/details/79208205)
[游戏列表](http://blog.csdn.net/m0_38082783/article/details/79035621)