preface
In the current front-end world, the three frameworks are rampant, and native JavaScript is used less and less. But I think JavaScript, as the foundation of every front-end engineer, can't be learned too many times.
Therefore, I decided to sort out the knowledge points that are easy to be ignored or confused in JavaScript, write a series of articles, and systematically and completely take you through the basic JavaScript in the way of soul torture, so as to bring you a different experience.
Links to series articles:
- [interview weapon] how many questions can you answer for the soul torture of native JS (I)
- [interview weapon] how many questions can you answer for the soul torture of native JS (2)
JavaScript arrays
Question 27: will those array methods modify the original array? Those won't?
This is an important test site. When I looked at the front-end interview question of Niuke, this question appeared repeatedly.
- Methods to change its own value (9 in total)
pop push shift unshift splice sort reverse // ES6 NEW copyWithin fill
- Method of not changing its own value
join // Return string forEach // No return value concat map filter slice // Returns a new array every some // Returns a Boolean value reduce // It doesn't have to return anything indexOf lastIndexOf // Return value (index value) // ES6 NEW find findIndex
Question 28: what are the return values of shift and unshift?
- unshift() inserts an element at the beginning of the array, and shift() deletes the first element of the array
- For both return values, test the code directly:
const arr = [1,2,3,4,5] undefined console.log(arr.unshift(0)) // 6 console.log(arr.shift()) // 0
As can be seen from the above code: unshift returns the number of new array elements after inserting elements, and shift returns the value of deleted elements.
By analogy, push returns the new array element format of the inserted element, and pop returns the deleted element value.
Question 29: what is the difference between new Array() and Array.of()?
- The Array.of() method creates a new Array instance with a variable number of parameters, regardless of the number or type of parameters. This seems to be very close to the function of new Array. Why did ES6 add a new method?
The reason is that when new Array(n) has only one parameter, it constructs not an array containing only N, but a 1*n array with all values undefined. See the test for details:
Array.of(7); // [7] Array.of(1, 2, 3); // [1, 2, 3] Array(7); // [ , , , , , , ] Array(1, 2, 3); // [1, 2, 3]
Question 30: can you use the splice () method flexibly? What is the return value of splice()?
- Basic use
Syntax:
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
Parameters:
- Start: Specifies the start position of the modification (counted from 0)
- deleteCount (optional): integer indicating the number of array elements to be removed.
- item1, item2... (optional): elements added to the array
Return value: an array composed of deleted elements. If not deleted, an empty array is returned.
2. Insert elements into the array
The array only provides methods of inserting and deleting at the beginning and end of the array, not at the middle position, but the insertion effect can be achieved by setting deleteCount to 0.
const arr = [1,2,3,4,5] console.log(arr.splice(2,0,100)) // [] console.log(arr) // [1, 2, 100, 3, 4, 5]
Question 31: is there anything you should pay attention to when slice () deletes elements?
When you see this problem, you may feel a little confused. It should be difficult to think of it if you haven't encountered it. Let me assume a scene and you will understand it.
Now there is such an array [1, - 1,2, - 1, - 5], I want to delete all negative numbers, so I write the following code:
const arr = [1,-1,-2,1,-5] for(let i = 0; i<arr.length; i++) { if (arr[i] < 0) { arr.splice(i, 1) } } console.log(arr) // [1, -2, 1]
That's strange. Why -2 hasn't been deleted? I'll print a sentence in the above code, and you should understand it.
for(let i = 0; i<arr.length; i++) { if (arr[i] < 0) { arr.splice(i, 1) console.log(a[i]) // -2 undefined } }
After - 1 is deleted from the array, the current i value is - 2. This traversal ends with i + +, which is just empty of the - 2 element. Therefore, if the splice deletion occurs in the array, be sure to pay attention to the position of the callback i.
Question 32: can you use reduce()?
- Cumulative multiplication
function Accumulation(...vals) { return vals.reduce((t, v) => t + v, 0); } function Multiplication(...vals) { return vals.reduce((t, v) => t * v, 1); }
- Instead of reverse
function Reverse(arr = []) { return arr.reduceRight((t, v) => (t.push(v), t), []); }
- Flatten arrays
function Flat(arr = []) { return arr.reduce((t, v) => t.concat(Array.isArray(v) ? Flat(v) : v), []) }
- Reverse string
[..."hello world"].reduce((a, v) => v + a) [..."hello world"].reverse().join('')
- Verify that the brackets are legal
// This is a very clever usage. If the result is equal to 0, the number of parentheses is legal. [..."(())()(()())"].reduce((a,i)=> i === '(' ? a+1 : a-1 , 0);
Question 33: how to use map, filter, every and some?
- map(): create a new array. The result is that each element in the array is the return value after calling the provided function once. The original array will not change.
// Returns the square root of numbers var numbers = [1, 4, 9]; var roots = numbers.map(Math.sqrt); // [1, 2, 3]
- filter(): creates a new array containing all the elements of the test implemented by the provided function.
// Filter excludes all smaller values function isBigEnough(element) { return element >= 10; } var filtered = [12, 5, 8, 130, 44].filter(isBigEnough); // filtered is [12, 130, 44]
-
some: used to detect whether the elements in the array meet the specified conditions.
- If one element satisfies the condition, the expression returns true, and the remaining elements will not be detected
- If there is no element that meets the condition, false is returned
// Detects whether any element in the array is greater than 10 function isBiggerThan10(element, index, array) { return element > 10; } [2, 5, 8, 1, 4].some(isBiggerThan10); // false [12, 5, 8, 1, 4].some(isBiggerThan10); // true
-
every: checks whether all elements of the array meet the specified conditions
- If an element in the array is detected to be unsatisfactory, the entire expression returns false and the remaining elements will not be detected
- Returns true if all elements meet the criteria
// Detects whether all elements in the array are greater than 10 function isBigEnough(element, index, array) { return element >= 10; } [12, 5, 8, 130, 44].every(isBigEnough); // false [12, 54, 18, 130, 44].every(isBigEnough); // true
Question 34: how many traversal methods do arrays have and how efficient are they?
Question 35: how to realize array disorder?
- Math.random
When it comes to disorder, you will first think of using Math.random, such as the following code:
var values = [1, 2, 3, 4, 5]; values.sort(function(){ return Math.random() - 0.5; }); console.log(values)
Math.random() - 0.5 randomly get a positive number, negative number or 0, and then sort to achieve disorder.
However, the effect of this method is not satisfactory. For specific tests, please refer to the blog: Disorder of JavaScript topics
- Fisher Yates shuffle algorithm
function shuffle(a) { var j, x, i; for (i = a.length; i; i--) { j = Math.floor(Math.random() * i); x = a[i - 1]; a[i - 1] = a[j]; a[j] = x; } return a; }
Question 36: do you know how many methods of array de duplication?
- Solution 1: use dual for and splice
function unique(arr){ for(var i=0; i<arr.length; i++){ for(var j=i+1; j<arr.length; j++){ if(arr[i]==arr[j]){ //The first is equivalent to the second, and the splice method deletes the second arr.splice(j,1); // After deletion, pay attention to callback j j--; } } } return arr; }
- Add a new array using indexOf or includes
//Use indexof function unique(arr) { var uniqueArr = []; // New array for (let i = 0; i < arr.length; i++) { if (uniqueArr.indexOf(arr[i]) === -1) { //indexof returns - 1, indicating that the element does not exist in the new array uniqueArr.push(arr[i])//If there are no elements in the new array, push them in } } return uniqueArr; } // Use includes function unique(arr) { var uniqueArr = []; for (let i = 0; i < arr.length; i++) { //includes detects whether the array has a value if (!uniqueArr.includes(arr[i])) { uniqueArr.push(arr[i])// } } return uniqueArr; }
- After sort, use the idea of fast and slow pointers
function unique(arr) { arr.sort((a, b) => a - b); var slow = 1, fast = 1; while (fast < arr.length) { if (arr[fast] != arr[fast - 1]) { arr[slow ++] = arr[fast]; } ++ fast; } arr.length = slow; return arr; }
The sort method is used to sort from small to large (return a new array). If there is no callback above in its parameters, the function will have a sort error when there are two or more digits (if omitted, the elements will be sorted according to the Unicode sites of each character of the converted string. The two digits will be calculated by changing into a string with a length of two).
4. Set de duplication provided by ES6
function unique(arr) { const result = new Set(arr); return [...result]; //Use the extension operator to convert the Set data structure to an array }
The elements in the Set only appear once, that is, the elements in the Set are unique.
5. Use the hash table to store whether the element appears (map provided by ES6)
function unique(arr) { let map = new Map(); let uniqueArr = new Array(); // Arrays are used to return results for (let i = 0; i < arr.length; i++) { if(map.has(arr[i])) { // If there is this key value map.set(arr[i], true); } else { map.set(arr[i], false); // If there is no key value uniqueArr.push(arr[i]); } } return uniqueArr ; }
A map object holds key value pairs, similar to an object. However, the key of map can be of any type, and the key of object can only be of string type.
If there are only numbers in the array, you can also use ordinary objects as hash tables.
6. filter with indexOf
function unique(arr) { return arr.filter(function (item, index, arr) { //Current element, the first index in the original array = = the current index value, otherwise the current element is returned //If it is not, it will prove to be a duplicate, so it will be discarded return arr.indexOf(item) === index; }) }
There may be questions here. Let me give an example:
const arr = [1,1,2,1,3] arr.indexOf(arr[0]) === 0 // First appearance of 1 arr.indexOf(arr[1]) !== 1 // Note 1 has appeared before
- reduce with includes
function unique(arr){ let uniqueArr = arr.reduce((acc,cur)=>{ if(!acc.includes(cur)){ acc.push(cur); } return acc; },[]) // [] is the initial value of the first parameter of the callback function return uniqueArr }
Question 37: do you know how to convert a class array into an array?
- Array.prototype.slice.call()
const arrayLike = { 0: '111', 1: '222', length: 2 } console.log(Array.prototype.slice.call(arrayLike)) // ["1", "2"]
- Array.from()
Array.from is a new method in ES6, which can convert * * class array objects and iteratable * * into real arrays.
const arrayLike = { 0: '1', 1: '2', length: 2 } console.log(Array.from(arrayLike)) // ["1", "2"]
- (...) extension operator
The extension operator calls the traversal interface. If an object does not deploy this interface, the conversion cannot be completed.
The... Operator cannot be used in the ordinary class array written by ourselves.
const arrayLike = { 0: '1', 1: '2', length: 2 } // Uncaught TypeError: arrayLike is not iterable console.log([...arrayLike]) // ["1", "2"]
If you deploy an ergodic interface, such as the arguments class array, you can use the extension operator.
function fn() { console.log([...arguments]) } fn(1,2,3) // [1, 2, 3]