See Github for more details

Interview handwritten JS-nuggets (juejin. Cn)

Handwritten deep copy

  • The first thing that came to my mind
JSON.parse(JSON.stringify());
Copy the code

But he had some problems

  1. Circular references cannot be resolved
  2. Unable to copy special objects such as RegExp, Date, Set, Map, etc
  3. Unable to copy function (emphasis).

Interview sufficient version

function deepClone(obj){
  if(typeofobj ! = ='object' || obj === null) {return obj
  }
  let copy = {}
  if (obj.constructor === Array){
    copy = []
  }
  for( let key of obj){
    if(obj.hasOwnProperty(key)){
      obj[key] = deepClone(obj[key])
    }
  }
  return copy
}
Copy the code

Write a new

process

  • A brand new object is created
  • The proTO of the new object created points to the constructor’s prototype
  • Execute the constructor and change the reference to this via call,apply
  • Make sure you return an object. The return value of type Object is returned as the return value of the new method. Otherwise return the above brand new object
function myNew(fn, ... args) {
    let instance = Object.create(fn.prototype);
    let res = fn.apply(instance, args); // Change this pointer

    // Make sure to return an object (in case fn is not a constructor)
    return typeof res === 'object' ? res: instance;
}
Copy the code

Implementing a Call

  • Take a function as an argument to an object
  • Execute the &delete function
  • Execute the function by specifying this to the function and passing in the given argument
  • If no argument is passed, it points to window by default
Function.prototype.myCall = function(context = window. args){
  let key = Symbol('key')
  context[key] = this
  letresult = context[key](... args)delete context[key]
  return result
}
function f(a,b){
  console.log(a+b)
  console.log(this.name)
 }
 let obj={
  name:1
 }
 f.myCall(obj,1.2) // Otherwise this points to window
 This function is executed inside the context. So this naturally inherits
Copy the code

Implement an Apply

  • The arguments passed in are arrays
Function.prototype.myApply = function(context = window. args){
  let key = Symbol('key')
  context[key] = this
  let result = context[key](args)
  delete context[key]
  return result
}
function f(a,b){
  console.log(a,b)
  console.log(this.name)
 }
 let obj={
  name:'Joe'
 }
 f.myApply(obj,[1.2])  //arguments[1]
Copy the code

Implement a bind

  • Bind returns a function. There are two ways to call the location. One is to call it directly. One way is through new, so let’s just call it directly

  • For direct calls, we chose apply, but for parameters we need to be aware of the following: Since bind can implement code like f.bind(obj, 1)(2), we need to concatenate the parameters

  • And finally by new, in the case of new, this will not be changed in any way, so in that case we need to ignore this passed in

Function.prototype.myBind = function (context, ... outerArgs) {
  let self = this
  return function F(. innerArgs){
    if(self instanceof F){
      return newself(... outerArgs,... innerArgs) }return self.apply(context,[...outerArgs,...innerArgs])
  }
}
function f(a,b){
  console.log(a+b)
  console.log(this.name)
 }
 let obj={
  name:1
 }
/ / f. may yCall (obj, 1, 2)
 f.myBind(obj, 1) (2)
Copy the code

Object.create

The object.create () method creates a new Object, using an existing Object to provide a proTO for the newly created Object

function create(proto) {
  function F() {}
  F.prototype = proto;

  return new F();
}
Copy the code

Implement the inheritance of those things

The most recommended

function Parent5 () {
  this.name = 'parent5';
  this.play = [1.2.3];
}

function Child5(){
  Parent5.call(this)
  this.type = 'woi'
}
Child5.prototype = Object.create(Parent5.prototype)
Child5.prototype.constructor = Child5
console.log(new Child5())
Copy the code

JSON.parse JSON.stringfy

Regular match

Must (always can’t learn)

Flattening of objects

See the Github repository for the code

Focus on the add (1) (2) (3)

I also found some code examples on the Internet. What are they

Correct version of results

// console.log(add(1)(2)(3)(4, 5)())
function addCurry(. args){return args.reduce((a,b) = > {
    return a+b
  }
)}
function currying(fn){
	let args=[]
	return function temp(. newArgs){
		if(newArgs.length){
			args = [...args, ...newArgs]
			return temp
		} else {
			let val = fn.apply(this, args)
			args = []
			return val
		}
	}
}
let add = currying(addCurry)
console.log(add(1) (2) (3) (4.5) ())console.log(add(1) (2) (3.4.5) ())console.log(add(1) (2.3.4.5) ())Copy the code

But there is still a problem with the final (). Can big brother solve it?

Implementing a JS function has to be currified

The definition of currization is to receive some parameters, return a function to receive the rest of the parameters, after receiving enough parameters, execute the original function

Core idea: through the length attribute of the function, obtain the number of parameters of the function, the number of parameters is the required number of parameters

function curry(fn,myargs){
  // console.log(fn)
  // console.log(fn.length)
  var length = fn.length
  var myargs = myargs || []
  return function(. args){
    newArgs = myargs.concat(args)
    console.log(newArgs)
    if (newArgs.length < length){
      return curry.call(this,fn,newArgs)
    }else{
      return fn.apply(this,newArgs)
    }
  }
}

function multiFn(a, b, c) {
  return a * b * c;
}
var multi = curry(multiFn);

console.log(multi(2) (3) (4))
/ / multi (2 and 4);
/ / multi (2) (3, 4);
/ / multi (2, 3) (4)
Copy the code

Quick sort

The idea is to use recursion. Take a value from an array, iterate through it and put the larger value on the right stack, the smaller value on the left stack. Then do the same for the left and right stacks

function quickSort(args){
  let length = args.length
  if (length<=1) {
    return args
  }
  let mid = Math.floor(length/2)
  let midVal = args[mid]
  let left = []
  let right = []
  for(let i = 0 ; i < length ; i++){
    if( i === mid ){
      continue
    }
    if (args[i] <= midVal){
      left.push(args[i])
    }else{
      right.push(args[i])
    }
  }
  return quickSort(left).concat([midVal]).concat(quickSort(right))
}
console.log(quickSort([2.3.1.6]))
Copy the code