Array 1
Author A had an interview A few days ago, during which interviewer B asked forEach and Map.
B: Have you heard about forEach?
A: used
B: Do you know the difference between for and forEach?
A: That doesn’t seem like much… Abba abba), sorry, no.
Then Barabbas pulled.
B: Can you write a map by hand?
A: em… Map returns an array with one or two parameters. Slow down your code as you work on the problem. Em, sorry, no.
forEach
Grammar:
arr.forEach(callback(currentValue [, index [, array]])[, thisArg]);
Copy the code
Note:
- ForEach is called without changing the original array, which is the array it was called from
- The scope of forEach() traversal is determined before the first callback is called. Items added to the array after a call to forEach are not accessed by the callback. If an existing value is changed, the value passed to the callback is the value that forEach() traversed up to their moment. Deleted items are not traversed.
- ThisArg has a value. When callback is called, this refers to thisArg. If omitted, or thisArg is null or undefined, this refers to the global object.
Description: 1,2
Var arr = [0]; arr.forEach(item => { arr[0]++; // check if changing the arr value affects item, and check if increasing the arr length affects the number of runs item++; // Verify that changing item affects arr console.log(item); // the output is 1,2,3 arr.push(3); }); console.log(arr); [3,1,2,3,3,3]Copy the code
That is, the arR length does not affect the number of times the callback is executed (if it does, arR [0] should be 6 instead of 3), indicating the length of the array that was called before callback was called. Changes to item do not affect the original array ARR, that is, its array values have been shallow-copied or deep-copied
Verify: inside is deep copy or shallow copy
Var BRR = [0, [3, 4]]. brr.forEach(item=>{ brr[3][0] = 1; console.log(item); //0 1 2 [1,4]});Copy the code
That is, shallow copy
Validation: The third argument to the callback function is its array
Var BRR = [0]; brr.forEach((item, index, tempArr)=>{ tempArr[2] = 5; console.log(item); / / 0 1 5});Copy the code
Handwritten forEach:
Array.prototype.myForEach = function(callback, thisArg) { //1. If (this == null) {throw new TypeError("this is null or not defined"); } //2. If (typeof callback! == "function") { throw new TypeError(callback + ' is not a function') } //3. Var whoArr = Object(this); Var len = whoarr. length >>> 0; Var k = 0; If (k in whoArr) {callback.call(thisArg, whoArr[k], k, whoArr); } k++; }} / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- test let arr = [0]; arr.myForEach(item=>{ console.log(item); / / 1, 2, 3});Copy the code
Extension (difference between for and forEach)
ForEach cannot be interrupted by breaks if a break is added to the forEach
Let arr = [0]; arr.myForEach(item=>{ break; console.log(item); / / 1, 2, 3});Copy the code
ForEach uses a return with no return value, while handwriting just calls a callback. Using return inside of for directly returns an error
map
Array.prototype.map()
The map() method creates a new array with the result that each element in the array is the return value from a call to the provided function.
Grammar:
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
}[, thisArg])
Copy the code
Callback three parameters: 1. The current value. 3. Current array (optional)
ThisArg: this points to callback
Note: developer.mozilla.org/zh-CN/docs/…
- The map method calls each element of the original array one time in order, and the return value (including undefined) from each execution forms a new array. The callback function is called only on indexes that have a value, but not on indexes that have never been assigned a value or deleted using delete.
- Map does not modify the array itself, but it can change the array when the callback is executed
- The number of times the map processes array elements is determined when the callback is first called. The existing array element is changed, and the value passed to callback is the value at which the map accessed the element. The element cannot be accessed if it is deleted after the map function is called but before it is accessed.
Implementation:
Array.prototype.myMap = function(callback, thisArg = undefined) {//2. Decide whether incoming first parameter is a function if (Object. The prototype. ToString. Call (the callback)! = "[object Function]") { throw new TypeError(callback + "is not a function"); } / / 3. An array type exception handling the if (this = = = undefined | | this = = = null) {throw new TypeError (" always read a property 'myMap of null or undefined"); } //4. Const o = object (this); Let len = o.length >>> 0; let len = o.length >> 0; //6. Create a new Array to return const arr = new Array(len); For (let I =0; i<len; i++) { if(i in o) { let val = o[i]; Call (thisArg, val, I, o); thisArg (val, I, o); Arr [I] = res; }} //10. } / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- testing const arr = [0]; const arr1 = arr.myMap(item=>item+1); console.log(arr1);Copy the code
reduce
Developer.mozilla.org/zh-CN/docs/…
Array.prototype.reduce()
Reduce () This method performs a function (ascending) that you provide on each element in the array, summarizing its results into a single return value.
Grammar:
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
Copy the code
Callback contains four parameters: Accumulator is the accumulated value returned by the last callback, and is the current element of the currentValue array, index is the current index, and array is the array calling Reduce
InitialValue: Cumulative value as the first call to the callback function. If not, the first element of the array is used. No initialValue calling reduce on an empty array with no initialValue will report an error.
Description:
- InitialValue has a value. Therefore, when the callback is executed for the first time, the Accumulator value is initialValue and currentValue is the first value of the array. InitialValue is not provided, so when the first callback is executed, accumulator will be the first value in the array. , currentValue is the second value in the array.
- The array for calling reduce is empty. If the array has only one element and no initialValue is provided, or if initialValue is provided but an empty array [], the unique value is returned and
callback
Will not be executed.
let count = 0;
console.log([, 1, 2].reduce((prev, cur) => {
count++;
return prev + cur;
}));
console.log(count);
Copy the code
From this we know: If no initialValue is passed in, then accumulator will find the first non-empty value in the call array. Cur is the next value of this array (if there is no next value, accumulator will be directly returned) and perform the first callback function.
Implementation:
Array.prototype.myReduce = function (callback, initialValue) { //1. Determining if a callback function if (Object. The prototype. ToString. Call (the callback)! = "[object Function]") { throw new TypeError(callback + "is not a function"); } / / 2. Call an array type exception handling the if (this = = = undefined | | this = = = null) {throw new TypeError (" always read a property 'myReduce' of null or undefined"); Let o = Object(this); Let len = o.length >>> 0; InitialValue let accumulator = initialValue; Let I =0; If (accumulator == undefined) {//8. While (I <len) {//9. If (I in o) {accumulator = o[I]; //1. If I is an accumulator, I ++ is an accumulator. break; } //10. Index ++ is empty; If (I > len) {throw new TypeError("Each element of the array is empty"); if(I > len) {throw new TypeError("Each element of the array is empty"); }} //13. i<len; If (I in o) {//15. Accumulator = callback. Call (undefined, accumulator, o[I], I, o)}} //16. Return accumulator; } console.log([, 1, 2, , 3].reduce((prev, cur) => { return prev + cur; })); console.log([, 1, 2, , 3].myReduce((prev, cur) => { return prev + cur; }));Copy the code
filter
Creates a new array that contains all the elements of the tests implemented through the provided function.
Developer.mozilla.org/zh-CN/docs/…
Grammar:
var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
Copy the code
Note:
- Callback will only be called on assigned indexes, not indexes that have been deleted or never assigned
- Filter does not alter the original array; it returns the filtered new array
- The traversal scope of filter is determined before the first callback is called.
Implementation:
Array.prototype.myFilter = function (callback, thisArg) { //1. Determining if a callback function if (Object. The prototype. ToString. Call (the callback)! == "[object Function]") { throw new TypeError(callback + "is not a function"); } / / 2. Determine whether this legal if this = = = undefined | | this = = = null) {throw new TypeError (" always read a property 'myFilter of null or undefined"); Let O = Object(this); Let len = o.length >>> 0; // create a new array let res = []; For (let I =0; i<len; I ++) {// skip empty if(I in O) {//8. If (callback.call(thisArg, O[I], I, O)) {res.push(O[I]); if(callback.call(thisArg, O[I], I, O)) {res.push(O[I]); }}} //9. } / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - test cases to the console. The log ([1, 2, 3]. The filter (item = > item > 1)); Console. log([1,2,3].myfilter (item => item > 1));Copy the code
conclusion
Learn, learn, learn