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
- Circular references cannot be resolved
- Unable to copy special objects such as RegExp, Date, Set, Map, etc
- 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