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

Fn. call(obj, 10, 20, 30) fn.apply(obj, [10, 20, 30]) Call performance is better than apply performance (especially when more than three parameters are passed to the function), so you can use call more often in later development

let arr = [10.20.30]
obj = {}
function fn(x, y, z) {} fn.apply(obj, arr) fn.call(obj, ... arr)The ES6-based expansion operator also allows you to pass each item in an array to a function at a time

Copy the code

Implement performance test: any code performance test is related to the test environment, such as CPU, memory, GPU, etc. The current performance of the computer will not be the same situation, different browsers will also lead to different performance

// console.time Can test the execution time of a program
// console.profile() Install Firebug in Firefox to get a more accurate picture of how much time each step takes
console.time('A')
for(let i = 0; i< 100000; i++) {
	
}
console.timeEnd('A')
Copy the code

2. Implement (5).add(3).minus(2), so that the output result is: 6

~function() {
  // After each method is executed, an instance of the type number must be returned so that the method can be used to continue calling the number prototype
  function check(n) {
  	n = Number(n);
    return isNaN(n)? 0 : n;
  }
	function add(n){
    n = check(n)
  	return this + n
  }
  function minus(n) {
    n = check(n)
  	return this -n
  }
  
  Number.prototype.add = add;
  Number.prototype.minus = minus

}()
Copy the code

3. What is the difference between arrow functions and ordinary functions? The constructor (function) can use new to generate strength, but can the arrow function be used?

The difference between arrow functions and normal functions:

  1. Arrow function syntax is much cleaner than normal functions (every function in ES6 can assign defaults and residual operators using parameters)
  2. The arrow function does not have its own this; it inherits this from the context of the function (call/apply cannot change the reference of this).
let fn = x= > x + 1

// A normal function
let obj = {
	name: 'lanfeng'
}
function fn1() {
	console.log(this)
}
fn1.call(obj) // {name: "lanfeng"}

// Arrow function
let fn2 = () = > {
	console.log(this)
}
fn2.call(obj) //Window {parent: Window, opener: null, top: Window, length: 3, frames: Window,... }

document.body.onclick = () = > {
//=> this: window is not the body of the current operation
}

// Call the inigo function B as an argument to another function A, which can execute the function (N times, passable).
function each(arr, callback) {
  for(let i = 0; i < arr.length; i++) {
  	let item = arr[i],
        index = i;
    // Receives the result returned by the callback function, if false, terminates the loop
    let flag = callback.call(arr,item, index)
    if(flag === false) {
    	break;
    }
  }
}
each([10.20.30.40].function(item, index){
	// this: Array of primitive operations
})
Copy the code
  1. Arrow functions don’t have arguments, can only be based on… Arg gets the pass parameter set (array)
let fn = (. arg) = > {
	console.log(arguments) //Uncaught ReferenceError: arguments is not defined
  console.log(arg) // [10, 20, 30n]
}
fn(10.20.30)

Copy the code
  1. Arrow functions cannot be executed by new (arrow functions have no this and no prototype)

4. How to invert the case of a string (write lowercase to uppercase)

let str = "LanfengQIUqiu front end"
str = str.replace(/[a-zA-Z]/g.content= > {
	// Content: The result of each re match
  // Verify whether the letter is uppercase: Whether the letter is converted to uppercase is the same as before, which was uppercase: find the range of uppercase letters in the ASII table to determine
   return content.toUpperCase() === content ? content.toLowerCase() : content.toUpperCase()
})
console.log(str) / / LANFENGqiuQIU front end
Copy the code

5. Implement a string matching algorithm to check whether T exists in string s, if it does, return -1 if not (if not based on built-in methods such as indexOf/includes)

Loop over each item in the original string, truncate each item from its current position by t. length, and compare it with T. If not, continue the loop, return the current index if the same (end of loop)

(function() {
  /** * loop through each item in the original string, truncating each item from its current position to t. length, and then comparing it with T. If they are different, continue the loop, and return the current index if the same (end of loop) **/
	function myIndexOf(T) {
  	let lenT = T.length,
        lenS = this.length,
        res = -1
    if(lenT > lenS) return -1
    for(let i = 0; i < lenS- lenT + 1; i++) {
    	let char = this[i];
      if(this.substr(i,lenT) === T) {
      	res = i;
        break; }}return res
  }
  String.prototype.myIndexOf = myIndexOf
 
})();

 let S = 'zhufengpeixun',
      T = 'pei'
  console.log(S.myIndexOf(T))
Copy the code

Regular processing

(function() {
  /** ** exec method **/
	function myIndexOf(T) {
  	let reg = new RegExp(T),
        res = reg.exec(this);
    return res === null ? -1 : res.index;
  }
  String.prototype.myIndexOf = myIndexOf
 
})();

 let S = 'zhufengpeixun',
      T = 'pei'
  console.log(S.myIndexOf(T))
Copy the code

5. In the input box, how to check whether the entered URL is a correct one? For example, if a user enters a string, check whether it conforms to the FORMAT of the URL

let str = "https://lanfeng.blog.csdn.net/"
let reg = /^((http|https|ftp):\/\/)? (([\w-]+\.) +[a-z0-9]+)((\/[^/]*)+)? (\? [^ #] +)? (#. +)? $/i
Protocol: // HTTP/HTTPS/FTP
/ / 2. The domain name
// 3. Request path
// 4. Pass the question mark parameter
console.log(reg.exec(str))
Copy the code

6.

function Foo() {
	Foo.a = function() {
  	console.log(1)}this.a = function() {
  	console.log(2)}}// Treat Foo as a class and set the instance's public property method => instance.a ()
Foo.prototype.a = function() {
	console.log(3)}// Set the private property method to Foo as a normal object => foo.a ()
Foo.a = function() {
	console.log(4)
}
Foo.a(); / / 4
let obj = new Foo(); // obj can call the method foo.a on the prototype
obj.a(); //2 // Private property has a
Foo.a(); / / 1

Copy the code

7. Write code to realize lazy loading of pictures

  • It is an important solution of front-end performance optimization. Through delayed loading of pictures or data, we can accelerate the speed of page rendering and make the speed of opening the page faster for the first time. Only after sliding to a certain area, we can load the real picture, which can also save the load flow
  • Solution: Put all images that need lazy loading in a box and set the width and height and default placeholder. Start by leaving all img SRC empty. Place the real image address on img’s custom properties and hide img. Wait until all other resources have loaded before loading the image; For many images, the current image area should be fully displayed as the page scrolls before loading the actual image

8. Write a re to verify this rule: A string of 6 to 16 characters must contain both uppercase and lowercase letters and digits

let reg = / ^ (? ! ^[a-zA-Z]+$)(? ! ^ ([0-9] + $)? ! ^[a-z0-9]+$)(? ! ^ + $) [A - Z0-9] [A zA - Z0-9] {June 16th} /
Copy the code

9. It is a string of 1 to 10 characters consisting of digits, letters, and underscores (_)

let reg = / (? ! ^[a-zA-Z0-9]+$)^\w{1, 10}$/
Copy the code

$attr(name, value); $attr(name, value);

let ary = $attr('class'.'box') // Get all elements in the page whose class is box

function $attr(property, value) {
	let elements = document.getElementsByTagName(The '*'),
      arr = [];
  [].forEach.call(elements, item= > { 
    // Store the value of the property corresponding to the current element
  	let itemValue = item.getAttribute(property);
    if(property === 'class') {
    	// Style class attribute names are treated specially
      new RegExp('\\b' + value +'\\b').test(itemValue) ? arr.push(item) ? null
      return;
    }
    if(itemValue === value) {
    	// The obtained value and the passed value are verified successfully: the current value is what we want
      arr.push(item)
    }
  })
  
  return arr 
}
Copy the code

10. A string consisting of English letters and Chinese characters with Spaces before and after the English words using the re

let str = 'No do no die, you can you can't no beep beep',
    reg = /\b[a-z]+\b/ig;
str = str.replace(reg, value= > {
	return ' ' + value + ' ';
}).trim();
console.log(str) // No do no die, you can you can, can't no beep beep
Copy the code

11. Write a program to flatten an array and remove duplicates, resulting in an ascending array that does not repeat itself

let arr = [[1.2.3], [3.4.5.5], [6.7.8.9[11.12[12.13[14]]]],10]
arr = arr.flat(Infinity)

// Use array.prototype. flat as popularized in ES6
console.log(arr)
[...new Set(arr)]
arr = Array.from(new Set(arr).sort((a,b) = > z-b))

// Change the array to a string (no matter how many levels the array is in toString, it will end up as a comma-separated string)
arr = arr.toString().split(', ').map(item= > {
	return Number(item)
})

// json.stringify (arr) also flattens arrays
arr = JSON.stringify(arr).replace(/(\[|\])/g.' ').split(', ').map(item= > Number(item))

// recursive processing
~function () {
	function myFlat() {
    let result = [],
        _this = this;
    // Loop through each item in the arR and store the non-array items in the new array
    let fn = (arr) = > {
      for(let i = 0; i < arr.length; i++) {
      	let item = arr[i];
        if(Array.isArray(item)) {
        	fn(item);
          continue;
        }
        result.push(item)
      }
    	
    	};
    fn(_this);
    return result;
  }
  Array.prototype.myFlat = myFlat
}();
arr = arr.myFlat()

Copy the code

11. Constructors

function Dog(name) {
	this.name = name;
}
Dog.prototype.bark = function() {
	console.log('wangwang');
}
Dog.prototype.sayName = function() {
	console.log('my name is' + this.name)
}
// Based on the built-in new keyword, you can create an instance of Dog, SanMAO. The instance can retrieve the properties and methods on the prototype, implement a _new method, and simulate the result of the built-in new

// Fn is the class that is currently new
// The parameter information that arG needs to pass to the constructor later
function _new(Fn, ... arg) {
  //let obj = {}
  //obj.__proto__ = Fn. Prototype // create an empty object with its prototype chain pointing to Fn. Prototype
  let obj = Object.create(Fn.prototype) Fn.call(obj, ... arg)return obj
}
/** * let sanmao = new Dog(' sanmao '); 1. Form a private scope as normal function execution * + parameter assignment * + variable promotion * 2. By default, we create an object and let this in the function execute this object, which is an instance of the current class * 3. 4. By default, the created object is returned as **/
let sanmao = _new(Dog,'three hairs');

sanmao.bark(); // wangwang
sanmao.sayName(); //" My name is Sanmao"
console.log(sanmao instanceof Dog) // true
Copy the code

12. On array merging and sorting

let ary1 = ['A1'.'A2'.'B1'.'B2'.'C1'.'C2'.'D1'.'D2'];
let ary2 = ['A'.'B'.'C'.'D']
/ / the combined array is: [' A1 ', 'A2', 'A', 'B1, B2,' B ', 'C1, C2,' C ', 'D1, D2,' D '].
ary2 = ary2.map(item= > item + 'arashi peak')
let arr = ary1.concat(ary2)
arr = arr.sort((a,b) = > a.localeCompare(b)).map(item= >{
	return item.replace('arashi peak'.' ')})console.log(arr)
Copy the code
let ary1 = ['D1'.'D2'.'A1'.'A2'.'B1'.'B2'.'C1'.'C2'];
let ary2 = ['B'.'A'.'C'.'D']
/ / the combined array is: [' D1, D2, 'D', 'A1, A2,' A ', 'B1, B2,' B ', 'C1, C2,' C '].
let n = 0;
for(let i = 0; i< ary2.length; i++) {
	let item2 = ary2[i];
  for(let k = 0; k< ary1.length; k++) {
  	let item1 = ary1[k];
    if(item1.includes(item2)) {
    	n = k;
      continue;
    }
    break;
  }
  ary1.splice(n+1.0, item2)
}

console.log(arr)
Copy the code

13 timer is asynchronous programming: set the timer for each cycle, without waiting for the timer to trigger the execution, continue the next cycle (timer triggered, the cycle has ended)

for(var i = 0; i < 10; i++) {
  (function(i){
    setTimeout(() = > {
    	console.log(i)
    }, 1000)
  })(i)

}

/ / the second
for(var i = 0; i < 10; i++) {
  setTimeout(((i) = > {
    	return () = > {
      	console.log(i)
      }
    })(i), 1000)}// The third option can be based on the bind preprocessing mechanism, which can be passed to the function each time the function executes during the loop
for(var i = 0; i< 10; i++) {
	var fn = function(i) {
  	console.log(i)
  };
  setTimeout(fn.bind(null, i), 1000)}// Var becomes let
for(let i = 0; i < 10; i++) {
  setTimeout(() = > {
    	console.log(i)
    }, 1000)}Copy the code

14. Relevant variables

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

15.

{} == {} null == undefined; /** * == null; /** * == null; Null === undefined * 3. NaN == NaN * 4. [12] == '12' Object and string comparison, is the object toString converted to a string and then compared * 5. All other cases are converted to numbers (if the data type is different). Object to number: first converted to string, then converted to number string to number: NaN NaN [12] == true =>false [] == false => 0== 0= > true [] == 1 => 0== 1 false **/

ToString () is converted to a string, and then converted to a number
var a = {
	n: 0.toString: function () {
  	return  ++this.n
  }
};
// a.toString(); / / draw on at this time is no longer the Object. The prototype. ToString, draw on their private
if(a == 1 && a ==2 & a==3) {
	console.log(1)}// 2. Shift: delete the first item of the array, return the deleted item to the original array
var a = [1.2.3]
a.toString = a.shift
if(a == 1 && a == 2 && a==3) {
	console.log('Ok')}/ / 3.
Object.defineProperty(window.'a', {
	get: function() {	
    this.value ? this.value++ : this.value = 1
 
    return this.value
  }
});
if(a == 1 && a == 2 && a==3) {
	console.log('Ok')}Copy the code

16. Application of the principle of array push method

/** * array.prototype. Push = function(val) {this[this.length] = 1; } * * /

let obj = {
	2:3./ / = > 1
  3: 4./ / = > 2
  length: 2.// => 3 => 4
  push: Array.prototype.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 = 4
console.log(obj) 

Copy the code

17. Three classical sorting algorithms for arrays: bubble sort

/** * The bubble sort idea * compares the current item in the array with the next item, and if the current item is larger than the next item, the two items can be swapped (the larger item is later) **/
let ary = [12.8.24.16.1]

/** * bubble: implement bubble sort * ary[Array] the Array to be sorted *@return [Array] New Array after sorting h **/
function bubble(ary) {
  // The outer loop I controls the number of rounds to compare
  for(let i = 0; i<ary.length; i++) {
    // The inner loop controls the number of comparisons in each round
   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
}
let ary = [12.8.24.16.1]
ary = bubble(ary)
console.log(ary)
Copy the code

18. Three classical sorting algorithms for arrays: insert sort

/** * insert: implement insert sort * ary[Array] the Array to be sorted *@return [Array] New Array after sorting h **/
function insert(ary) {
  // 1. Prepare a new array to store the cards in your hand.
  let handle = [];
  handle.push(ary[0])
  for(let i = 1; i<ary.length; i++) {
    // A is A newly drawn card
  	let A = ary[1]
    // Compare it to the cards in the Handle (from back to front)
    for(let j = handle.length - 1; j>=0; j--) {
    	let B =  handle[j]
      
      // If the current new card A is bigger than B, place A after B
      if(A>B) {
      	handle.splice(j+1.0 , A)
        breadk;
      }
      // When it comes to the first item, we can put the new card in the front of the hand
      if(j===0) {
      	handle.unshift(A)
      }
    }
  }
	return handle
}
let ary = [12.8.24.16.1]
ary = insert(ary)
console.log(ary)
Copy the code

19. Three classic sorting algorithms for arrays: quicksort

/** * quick: implement quick sort * ary[Array] the Array to be sorted *@return [Array] New Array after sorting h **/
function quick(ary) {
  // end recursion (if ary is less than or equal to one item, do not handle)
  if(ary.length <=1) {
  	return aryy
  }
  // 1. Find the middle item of the array and remove it from your existing array
  let middleIndex = Math.floor(arry.length/2);
  let middleValue = ary.splice(middleIndex, 1) [0]
  
  // 2. Prepare the left and right arrays. Loop through the remaining items in the array, and place the items that are more familiar than the current item in the left array and vice versa
  let aryLeft = [],
      aryRight = [];
  for(let i = 0; i< ary.length; i++) {
  	let item = ary[i]
    item < middleValue ? aryLeft.push(item) : aryRight.push(item);
  }
  // 3. Recursively, the left and right arrays continue to do this until the left and right arrays are sorted
  
  return quick(aryyLeft)concat(middleValue, quick(aryRight));
}
let ary = [12.8.24.16.1]
ary = quick(ary)
console.log(ary)
Copy the code

20.

The sales volume of a company from January to December is stored in an object as follows: {1: 222, 2: 123, 5: [222, 123, NULL, NULL,888, null, null, null, null, null, null, null]

// The first method
let obj = {
	1: 222.2: 123.5: 888
}
let arr = new Array(12).fill(null).map((item, index) = > {
	return obj[index + 1] | |null
})
console.log(arr)

// The second method
let obj = {
	1: 222.2: 123.5: 888
}
obj.length = 13
let arr = Array.from(obj).slice(1).map(item= > {
 typeof item === 'undefined' ? null : item
})
console.log(arr)

// The third way
let obj = {
	1: 222.2: 123.5: 888
}

let arr = new Array(12).fill(null)
Object.keys(obj).forEach(item= > {
	arr[item-1] = obj[item];
})
console.log(arr)
Copy the code

21. Given two arrays, write a method to calculate their intersection

// The first method
let num1 = [1.2.2.1]
let num2 = [2.2]
// Output result [2, 2]

let arr = [];
for(let i = 0; i< num1.length; i++) {
	let item1 = num1[i]
  for(let k = 0; k< num2.length; k++) {
  	let item2 = num2[k]
    if(item1 === item2) {
     arr.push(item1)
      break; }}}console.log(arr)

// The second method
let num1 = [1.2.2.1]
let num2 = [2.2]
let arr = [];
num1.forEach(item= > {
	num2.includes(item) ? arr.push(item) : null
})
console.log(arr)
Copy the code

22.

Implement an add function that satisfies the following functions add(1); // 1 add(1)(2); // 3 add(1)(2)(3) // 6 add(1)(2)(3)(4); //10 add(1)(2, 3); // 6 add(1, 2)(3); / / 6 add (1, 2, 3); // 6 Function Curryification: the idea of pre-processing (using closure mechanisms)

let obj = {name: 'lanfeng'}
function fn(. arg) {
	console.log(this, arg)
}
// This => obj arg=> [100, 200, event object]
document.body.onclick = fn.bind(obj, 100.200);
// Bind returns an anonymous function. When the event is triggered, the anonymous function executes
document.body.onclick = function(ev) {
	//ev event object: an event binding method for each element that executes when an event is triggered and passes information about the current event to the function "event object"
}
Copy the code
function currying(fn, length) {
	length = length || fn.length;
  return function(. args) {
  	if(args.length >= length) {
    	returnfn(... args); }return currying(fn.bind(null. args), length-args.length); }}function add(n1, n2, n3) {
	return n1 + n2 + n3;
}
add = currying(add, 3)
console.log(add(1) (2) (3))
Copy the code

For more information, please pay attention to the following public account: