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)





 

原文地址:https://www.cnblogs.com/linewman/p/9918549.html