JavaScript summary 2.0— Summary and handwriting of the most complete array method
JS review 2.0 is mainly for the summary of array methods and detailed explanation of handwriting
handwritten array extension method
1. Check if it is an array
<script>
var arr = [1,2,3]
//Judge whether arr is an array, return boolean true or false
//Method 1: Array.isArray()
console.log(Array.isArray(arr));
//Method 2: instanceof
console.log( arr instanceof Array);
//Method 3: Determine whether the constructor of arr contains Array
console.log(arr.constructor.toString().indexOf('Array')>-1);
//arr.constructor is ƒ Array() { [native code] }
//Method 4: Use isPrototypeOf to judge whether arr exists in the prototype chain of Array
console.log(Array.prototype.isPrototypeOf(arr));
/*
Method 5: Universal Judgment Variable Type Method Object.prototype.toString.call()
will return a string like "[object XXX]"
*/
console.log(Object.prototype.toString.call(arr).indexOf('Array')>-1);
//that is console.log(Object.prototype.toString([])===Object.prototype.toString(arr));
</script>
2. Convert class array to array
An array-like object is an object that has a length property and is not an array, but structurally behaves like an array.
Array-like objects mainly include:
- argument
in ordinary functions
- Some methods for obtaining Dom collections, such as document.querySelectorAll(), document.getElementsByClassName, document.getElementsByTagName()
, etc. will also return array-like objects
<body>
<div>1</div>
<div>2</div>
<script>
let arg = document. querySelectorAll('div');
console.log(arg); //NodeList(2)
//Method 1: use Array.from
console.log(Array.from(arg)); //Array(2)
//method 2: extension operator
console. log([...arg]);
//Method 3: Use Array.prototype.slice.call(): the object with the length property can be converted into an array, because the slice method returns a new array
console.log( Array.prototype.slice.call(arg));
//If the slice method does not pass parameters, it will return a copy of the original array, which is realized through the explicit binding of the call so that the arguments can also call the slice method.
//Method 4: Use concat
console.log(Array.prototype.concat.apply([], arg));
</script>
</body>
3. Array flattening
Array flattening refers to changing a multidimensional array into a one-dimensional array
const arr = [1, [2, [3, [4, 5]]], 6]
// => [1, 2, 3, 4, 5, 6]
//Method 1: Use the built-in flat()
const res1 = arr. flat(Infinity)
//Method 2: use regular expressions
const res2 = JSON.stringify(arr).replace(/\[|\]/g,"").split(',')
//At this time, the array element is a string type, if you use arr.join(), the brackets will be automatically removed
//Method 3: Use reduce to implement the flat method of the array (focus)
function flatmy(ary) {
// Note that the function must return a value
return ary. reduce((pre, cur) => {
return pre. concat(Array. isArray(cur) ? flatmy(cur) : cur)
}, [])
}
console. log(flatmy(arr))
// Method 4: Function recursion
const res4 = []
const fn = (arr) => {
for (let i = 0; i < arr. length; i++) {
if (Array.isArray(arr[i])) {
fn(arr[i])
} else {
res4.push(arr[i])
//or res4 = res4.concat(arr[i])
}
}
return res4
}
console. log(fn(arr))
//Method 5: call toString
console.log(arr.toString()); //1,2,3,4,5,6
console.log(arr.toString().split(',').map(item => item-0)) //If there is no implicit conversion of the map function, the elements in the array are of string type
4. Array deduplication
const arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}]
// => [1, '1', 17, true, false, 'true', 'a', {}, {}]
// Method 1: Use the new Set method
let res = Array. from(new Set(arr))
// Method 2: use indexOf
let res2 = []
for(let v of arr){
if(res2. indexOf(v)==-1) res2. push(v)
}
/* Method 3: use filter */
function myUnique(arr){
return arr.filter((v,index)=>{
return arr.indexOf(v)===index
})
}
// Method 4: use sort, the same elements after sorting are in adjacent positions
function unique(arr) {
arr = arr. sort()
var res = []
for (var i = 0; i < arr. length; i++) {
if (arr[i] !== arr[i - 1]) {
res.push(arr[i])
}
}
return res
}
console. log(unique(arr))
5. Arrays use Math.max
Math.max supports passing in multiple parameters, but cannot pass in an array (otherwise it will be NaN
), if you want to use the following method
Math.max.apply(null,arr)
Math.max(...arr)
Handwritten array built-in method
1. Array.prototype.filter
The filter() method creates a new array containing all elements that pass the test fulfilled by the provided function
Syntax: var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
parameter:
callback
: A function to test each element of the array. Returning true means the element passes the test and keeps the element, false doesn't. It accepts the following three parameters
element
: The element in the array currently being processed.
index optional
: The index in the array of the element being processed.
array optional
: The array itself on which filter was called.
thisArg Optional
: The value to use for this when the callback is executed.
Array.prototype.myFilter = function(callback,thisArg){
if(typeof callback != 'function' ) {
throw new TypeError(callback +'is not a function')
}
if(!Array.isArray(this)){
throw new TypeError('This method must be an array')
}
let res = []
//Determine the this point of the callback function, see if the second parameter is passed, if not, set it to window call
let context = arguments[1]||window
for(let i = 0; i < this.length; i++){
callback.call(context,this[i],i,this) && res.push(this[i])
}
return res
}
2. Array.prototype.map
The map() method creates a new array consisting of the values returned by calling the provided function once for each element in the original array
Syntax: var new_array = arr.map(function callback(currentValue[, index[, array]]) [, thisArg])
, the parameters are roughly the same as filter
Array.prototype.myMap = function (callback, thisArg) {
if (typeof callback != 'function') {
throw new TypeError(callback + 'is not a function');
}
if (!Array.isArray(this)) {
throw new TypeError('This method must be an array');
}
let res = []
let context = arguments[1] || window
for (let i = 0; i < this. length; i++) {
res.push(callback.call(context, this[i], i, this))
}
return res
};
3. Array.prototype.reduce (difficulty)
The reduce() method sequentially executes a reducer function provided by you for each element in the array. Each run of the reducer will pass in the calculation results of the previous elements as parameters, and finally aggregate the results into a single return value
Syntax: Array.reduce(callback(previousValue, currentValue[, currentIndex[, array]])[, initialValue])
parameter:
previousValue
: The return value of the last callbackFn call. The initial value initialValue||array[0]
when called for the first time
currentValue
: The element in the array being processed. If initialValue is specified in the first call, its value is array[0], otherwise it is array[1].
currentIndex
: the index of the element in the array being processed
initialValue
: Optional, as the value of the previousValue parameter when the callback function is called for the first time. If initialValue is specified, currentValue
will use the first element of the array
Array.prototype.myReduce = function (callback, initialValue) {
if (typeof callback != 'function') {
throw new TypeError(callback + 'is not a function');
}
if (!Array.isArray(this)) {
throw new TypeError('This method must be an array');
}
let accumulator = initialValue
if(accumulator === undefined){
//If the initial value is not set, assign it to the first element of the array
accumulator = this[0]
//When the array is empty and the initial value initialValue is not provided, an error will be reported
if(accumulator === undefined) throw new TypeError('The array must be non-empty when there is no initial value');
}
//If the initial value is given, the starting index number is 0
let startIndex = initialValue !== undefined ? 0 : 1;
for (let i = startIndex; i < this. length; i++) {
accumulator = callback. call(undefined, accumulator, this[i], i, this);
}
return accumulator;
};
4. Array.prototype.forEach
The forEach() method executes the given function once for each element of the array, note that the return value is undefined
Syntax: arr.forEach(callback(currentValue [, index [, array]])[, thisArg])
PS: If you want to jump out of the forEach loop, you can use try....catch to achieve
Array.prototype.myForEach = function (callback, thisArg) {
if (typeof callback != 'function') {
throw new TypeError(callback + 'is not a function');
}
if (!Array.isArray(this)) {
throw new TypeError('This method must be an array');
}
let context = arguments[1] || window;
for (let i = 0; i < this. length; i++) {
callback. call(context, this[i], i, this);
}
};
5. Array.prototype.some
The some() method tests whether at least 1 element in the array passes the provided function test. It returns a value of type Boolean.
Syntax: arr.some(callback(element[, index[, array]])[, thisArg])
Array.prototype.mySome = function(callback,thisArg){
if (typeof callback != 'function') {
throw new TypeError(callback + 'is not a function');
}
if (!Array.isArray(this)) {
throw new TypeError('This method must be an array');
}
let context = arguments[1] || window
for(let i =0 ; i < this.length; i++){
if(callback.call(context,this[i],i,this)){
return true
}
}
return false
}
6. Array.prototype.unshift
The unshift() method adds one or more elements to the beginning of the array and returns the new length of the array (this method modifies the original array)
Syntax: arr.unshift(element1, ..., elementN)
Array.prototype.myUnshift = function () {
if (!Array.isArray(this)) {
throw new TypeError('This method must be an array');
}
let len = arguments. length;
this.length += len;
//Pay attention to looping from back to front to prevent the later values from being overwritten as the previous arguments
for (let i = this.length - 1; i >= 0; i--) {
//When i is less than the passed parameter, take the passed parameter, otherwise take the original value
this[i] = i < len ? arguments[i] : this[i - len];
}
return this. length;
};
7. Array.prototype.join
The join() method joins all elements of an array (or an array-like object) into a string and returns the string. If the array has only one item, then that item will be returned without a separator
Syntax: arr.join([separator])
Parameters: separator
is optional, specify a string to separate each element of the array. Convert delimiter to string if needed. If this value is defaulted, array elements are separated by commas (,). If separator is the empty string (""), there will be no characters between any elements.
If an element is undefined or null, it is converted to an empty string
Array.prototype.myJoin = function (s = ',') {
if (!Array.isArray(this)) {
throw new TypeError('This method must be an array');
}
let str = '';
for (let i = 0; i < this. length; i++) {
//Determine whether the array element is undefined or null
if(this[i] === undefined || this[i] === null ) this[i] = ''
if (i === 0) str = `${this[i]}`;
else str = `${str}${s}${this[i]}`;
}
return str;
};
In addition, there are methods such as every, findIndex, includes, push, etc., which are relatively simple to implement, so I won’t repeat them here.