1. What is the difference between Call and apply, and which one has better performance?

Call and Apply are both Function prototype methods that can be called by each Function as an instance of Function. I can change the this point. The only difference between call and apply is that call passes parameters one by one, while apply passes parameters in an array.

Call performance is slightly better, especially with more than three parameters

Add (3). Add (2).

Number.prototype.add = function(n){ n = Number(n); // Increase fault tolerance n = isNaN(n)? 0:n; return this + n; Prototype. Minus = function(n){n = Number(n); n = isNaN(n)? 0:n; return this - n; } console.log((5).minus(4).add(1));} console.log((5).minus(4).add(1));Copy the code

3. What are the differences between arrow functions and ordinary functions? Constructors can use new to generate instances, but can arrow functions? Why is that?

Arrow functions are different from normal functions

1. Arrow functions are more concise

2. The arrow function does not have its own this. The this that appears in the arrow function belongs to the context in which the function is located (call, apply, etc.).

3. Arrow functions have no arguments

4. Arrow functions cannot be executed by new (arrow functions have no this and no prototype)

4. Implement a string matching algorithm to check whether string T exists in string S, if so, return the location, otherwise return -1.

String.prototype.myIndexOf = function (T){ let lenT = T.length; let lenS = this.length; let res = -1; if (lenT > lens) return -1; for(let i= 0; i<lenS-lenT+1; i++){ if(this.substr(i,lenT) === T){ res = i; break; } } return res; } let S = 'haohaoxuexi' let T = 'xue'; console.log(S.myIndexOf(T));Copy the code

5. Output the following code running results

//example1 var a = {}, b = '123', c=123; a[b] = 'b'; a[c] = 'c'; console.log(a[b]); Example 2 var a = {}, b =Symbol('123 '), c=Symbol('123 '); ; a[b] = 'b'; a[c] = 'c'; console.log(a[b]); // 'b' Symbol creates a unique value so Symbol('123')! == Symbol('123')//example3 var a={}, b={key:'123'}, c={key:'456'}; a[b]='b'; a[c]='c'; console.log(a[b]); // The 'c' object cannot be used as an attribute name of another object, so the object as a key is converted to a string. The toString method of the Object // converts the Object to '[Object Object]', so {'[Object Object]' in a: "C "} // obj = {} arr=[12,23] obj[arr]=' obj 'obj:{"12,23":" arr "} Array toString and Object toString there are some differencesCopy the code

6. Abnormal prototype chain

function Foo(){ Foo.a = function () { console.log(1); } this.a = function() { console.log(2); }} // Treat Foo as a class and set the method instance shared by the instance on the prototype. Foo.prototype.a = function() { console.log(3); } // Set the private property method foo.a () as an ordinary object; Foo.a = function () { console.log(4); } Foo.a(); //4 let obj = new Foo(); // execute Foo once, so foo. a is overwritten as output 1, and the prototype method a is overwritten as output 2 obj.a(); // 2 Foo.a(); / / 1Copy the code

7. Array flattening write a program to flatten the array, and remove the duplicate part of the data, finally get an ascending and not repeating array

1. Use array.prototype. flat in ES6

arr = arr.flat(Infinity)
arr = Array.from(new Set(arr)).sort((a,b) =>a-b);
Copy the code

2. Turn arrays into strings

arr = arr.toString().split(',').map(item => Number(item));
arr = Array.from(new Set(arr)).sort((a,b) =>a-b);
Copy the code

8. Write a new

function Dog(name){ this.name = name; } Dog.prototype.bark = function(){ console.log('wangwang'); } Dog.prototype.sayName = function(){ console.log('my name is ' + this.name); } requirements: Based on the built-in new keyword, we can create an instance of dog, SanMAO, which can call prototype methods and properties. The requirement now is that implementing a _new method of our own can simulate the results of the built-in newCopy the code

Things to do after New:

1. Create an instance of the class: Create an empty object obj and set obj.__proto__ to constructor prototype

2. Initialize instance: The constructor is passed arguments and called, and the this pointer is set to point to the instance obj

3. Return instance obj

function _new(Fn,... arg){ let obj = {}; obj.__proto__ = Fn.prototype; Fn.call(obj,... arg); return obj; } let sanmao = _new(Dog,' sanmao ');Copy the code

9. Variable scope

let fn = function AAA() { AAA = 1000; console.log(AAA); // Print the contents of this function in non-strict mode. AAA(); //Uncaught ReferenceError: AAA is not defined //1. Functions that are supposed to be anonymous cannot be called outside the function name, but can be called inside the function. And just like creating constants, the value stored by this name cannot be changed. In non-strict mode, no error is reported, but no effect is achieved. In strict mode, an error is reported directlyCopy the code

So:

var b = 10; (function b() { b = 20; console.log(b); // Output function itself})(); console.log(b); / / 10Copy the code

If we want the inside b to print 20 and the outside b to print 10, then the inside B must be private (var, let, const declaration or add a parameter b to the function).

A ==1 &&a ==2 &&a ==3

== If the two data types are different, the two data types are converted to the same data type

1.{} == {} two objects compare the address of the heap memory

2. null == undefined true  null === undefined false

NaN is not equal to anyone

4.[12] == ’12’ objects and strings are compared by converting toString () to strings

5. The rest of the cases are converted to numbers for comparison (if the data type is different)

Object to number: String to number first

String to number: Whenever a non-numeric character occurs, the result is NaN

Boolean to number: true–1 false — 0

Null converts to the number 0

Undefined goes to NaN

[12]==true    false

[] == false  true

[] == 1      false

true == 2    false

var a = ?
if(a == 1 && a ==2 && a == 3) {
    console.log(1);
}
Copy the code

Since objects and numbers are compared first with object.toString(), and toString is defined on the prototype, we can define the object itself to truncate toString to achieve our purpose

Var a = {n:0, toString: function(){return +this.n; }}; // let a = [1,2,3]; a.toString = a.shift; // Delete the first item of the array and return the deleted itemCopy the code

11. Object calls the push method

let obj = { 2:3, 3:4, length: 2, push: Array.prototype.push } obj.push(1); obj.push(2); console.log(obj); / / / / / / / / / / / / / / / / / / {2:3:1 2 length: 4 push: ƒ push ()}Copy the code

Array.prototype.push (source code simulation)

Array.prototype.push = function (val) { this[this.length] = val; //this. Length automatically +1!! Return this.length}Copy the code

So when the object calls push,

obj.push(1); // this:obj => obj[obj.length] = 1 => obj[2]=1 => obj.length = 3 obj.push(2); //this:obj =>obj [obj. Length]=2 =>obj [3]=2 =>obj. Length = 4Copy the code

12. Bubble sort

function bubble(ary) { let temp=null; for(var i=0; i<ary.length-1; i++){ for(let j=0; j<ary.length-1-i; j++){ if(ary[j] > ary[j+1]){ temp = ary[j]; ary[j] = ary[j+1]; ary[j+1] = temp; } } } return ary; }Copy the code

13. Insert sort

function insert(arr){ let handle = []; handle.push(arr[0]); for(var i=1; i<arr.length; i++){ for(var j=handle.length-1; j>=0; J -) {/ / from backward than can the if (arr [I] > handle [j]) {handle. Splice (j + 1, 0, arr [I]); break; } the if (j = = = 0) {/ / after the situation above Judgement here can only be arr [I] is smaller than handle the opening of the handle. The unshift (arr [I]); }}}}Copy the code

quicksort

function quick(arr){ if(arr.length<=1){ return arr; } let midIndex=Math.floor(arr.length/2); let midValue = arr.splice(midIndex,1)[0]; let arrLeft=[],arrRight=[]; for(let i=0; i<arr.length; i++){ let item=arr[i]; item<midValue? arrLeft.push(item):arrRight.push(item); } return quick(arrLeft).concat(midValue,quick(arrRight)); }Copy the code

15. Object to array

Let obj = {2, and "3, 8, 88,} / / the key representative in here Please put the data processing for the following structure [888 and 222123, null, null, null, null, null, null, null, null, null]Copy the code

So the array represents 12 months in which 1, 2, and 5 have values in this object so convert this object to this array

/ / method let arr = new Array (12). The fill (null). The map ((item, index) = > {return obj [index + 1] | | null; }); Obj. Length = 13; Let arr = array. from(obj).splice(1).map(item => {return typeof item === = "undefined"? null : item; }) // let arr = new Array(12).fill(null); Object.keys(obj).forEach(item => { arr[item - 1] = obj[item]; });Copy the code

Rotate the array

function rotate(k) {
    if (k<0 || k === 0|| k === this.length) return this;
    if(k > this.length) k = k%this.length;
    return this.slice(-k).concat(this.slice(0,this.length-k));
}
Array.prototype.rotate = rotate;
let arr = [1,2,3,4,5,6,7];
arr.rotate(3);
Copy the code

17. Handwritten map

About why can use the Object. The prototype. ToString. Call () data types:

JavaScript: reference Object. The prototype. The principle of the toString method – ZhiChunLi – blog park (cnblogs.com)

Array.prototype.myMap = function(fn,context){ if (Object.prototype.toString.call(fn) ! == "[object Function]"){ throw ('Error'); } let resArray = []; let curArray = this; for( let i =0; i<curArray.length; i++){ resArray[i] = fn.call(context, curArray[i], i,curArray); } return reaArray; } let arr = [3,4,5,6,7]; arr.myMap((item,index,arr) => {return item + 1})Copy the code