Image stabilization function
Cancels the previous delayed call method each time the event is emitted
* @param (fn, wait) fn- function, */ function debounce(fn, wait = 500) {let timer = null return function(... args) { if(timer) { clearTimeout(timer) } timer = setTimeout(() => { fn.apply(this, args) timer = null }, wait) } }Copy the code
- use
<input type="input" id="username" /> // JS const inputEL = document.querySelector('#username') const listenFn = debounce(function(event) { console.log(event.target.value) }, 200) inputEL.addEventListener('input', listenFn)Copy the code
Throttling function
Whatever happens, it must happen once in a while, right
* @param (fn, wait) fn- function, */ function throttle(fn, wait = 500) {let timer = null return function(... Args) {// The last timer task has not been executed, If (timer) {return} timer = setTimeout(() => {fn. Apply (this, args) timer = null}, wait)}}Copy the code
- use
function sayHi(e) {
console.log(e.target.innerWidth, e.target.innerHeight)
}
window.addEventListener('resize', throttle(sayHi, 2000))
Copy the code
Fibonacci numbers
The title comes from
The Rikon-Fibonacci series
Description:
- Write a function, input n, to find the NTH term of the Fibonacci sequence. The Fibonacci sequence is defined as follows:
F (0) = 0, F (1) = 1, F (N) = F (N - 1) + F (N - 2), where N > 1.Copy the code
The Fibonacci sequence starts with 0 and 1, and the Fibonacci numbers that follow are the sum of the previous two numbers. If the result is greater than 1000000007, you need to take the module. If the initial result is 1000000008, return 1.
Method 1: recursion + closure
/** * @description uses recursion + closure * @param {number} n * @return {number} */ const fib = function (n) {// cache, Const cache = new Map([[0, 0], [1, 1], [2, 1],]) If (cache.has(n)) {return cache.get(n)} // f(n) = f(n-2) + f(n-1) let result = inner(n-2) + inner(n-1) // Results over 1000000007, If (result > 1000000007) {result = result % 1000000007} result) return result } return inner(n) }Copy the code
Mode 2: Pure traversal (dynamic programming)
/** * @param {number} n * @return {number} */ const fib = function(n) {// Const map = new map ([[0, 0], [1, 1], [2, 1), ]) if(n <= 2) { return map.get(n) } let i = 3 let first = map.get(1) let second = map.get(2) while(i <= n) { let result = second + first if(result > 1000000007) {result = result % 1000000007} First = second second = result i++} return second}Copy the code
Handwritten call function
-
Principle: When a function is called as an object property, this refers to the object
-
Thoughts and ideas:
- To obtain
thisArg
Parameter and residual parameter - Access to call
call
Set the function tothisArg.func
On the properties - ThisArg. Func function is executed and the result is received
- Remove thisArg func function
- Return execution result
Function.prototype.myCall = function(thisArg, ... ThisArg = thisArg == null? window : ThisArg. Func = thisArg. Func; thisArg. Func = this; Const result = thisarg.func (... ThisArg. Func delete thisArg. FuncCopy the code
- Test myCall
function sayHello(time) { console.log(`${this.name} say ${this.word} at ${time}`); } const bottle = { name: 'violet-mio', word: 'hello'} // myCall changes the this pointer in sayHello to the bottle object, MyCall (bottle, new Date().tolocaletimeString ())) // Violet -mio say hello at 4:46:28 PMCopy the code
Handwritten bind
- To obtain
thisArg
andRemaining parameter args
- Get the function that calls myBind, save to
func
- Create a new return function
resultFn
In resultFn, do the following logic- Obtain the secondArgs when resultFn is executed, and merge args and secondArgs
- Determine whether to use the new keyword to execute the resultFn function
- If so, the this inside the resultFn function remains the same
- Otherwise, change this inside the resultFn function to
thisArg
- Execute through Apply
Function func
And returns the execution result
- Modify the prototype of the resultFn function to bind to
Object.create(func.prototype)
Function.prototype.myBind = function(thisArg, ... args) { thisArg = thisArg == null ? // keep calling myBind const func = this const resultFn = function(... SecondArgs) {const fullArgs = args. Concat (secondArgs) const fullArgs = args. Const realThis = this instanceof resultFn? this : thisArg return func.apply(realThis, Prototype = object.create (func.prototype) return resultFn}Copy the code
- Test myBind
Function Person(name, age) {console.log(' function call ') The __proto__ attribute of the instance object points to the constructor's Prototype console.log(' Use new', this.__proto__ === Person.prototype) this.name = name this.age = age } Person.prototype.sayHi = function() { Console. log('sayHi function execution '); console.log(this.name, this.age); } const obj = {name: 'I am the name of obj ', age: } const Student = person.bind (obj, 'name') // create Point with new, Const stu = new Student(' age') stu.sayHi() Const teaher = person.bind (obj, 'name') teaher()Copy the code
Write the Curry function
- Get the original function
fn
Is the length of an acceptable parameter - Define an array to cache the parameters in the recursive process
- Returns the keratology function to collect arguments
- In the Currization function
- Merge the current parameter with the previous parameter
- Determines whether an argument is greater than or equal to the length of an acceptable argument
- If true, execute the original function
- Otherwise, return the keratology function and continue the collection of parameters
Const curry = function (fn) {const limitLen = fn.length; Let params = [] return function _innerCurry(... Args) {// Merge parameters params = params.concat(args) // If the number of merged parameters is greater than or equal to the number of parameters accepted by fn if(params.length >= limitLen) {// Return the fn function Fn. apply(null, params)} else {// Return a currie function to collect the parameters return _innerCurry}}Copy the code
- Do not use coriolis
sum(2)(3)(5)
The calculation results of
function add(num1, num2, num3) {
return num1 + num2 + num3
}
const sum = function(a) {
return function(b) {
return function(c) {
return add(a, b, c)
}
}
}
console.log(sum(2)(3)(5))
Copy the code
- Use the function keratology
const curriedAdd = curry(add)
console.log(curriedAdd(2)(3)(5))
Copy the code
Implement the new operator
- Create an empty object that links the stereotype to the explicit stereotype of the constructor
- Execute the constructor to change this to an empty object and save the result
- The constructor returns the result if the object executes it; Otherwise return the obj object
function myNew(fn, ... Const obj = object.create (fn.prototype) const obj = object.create (fn.prototype); Const result = fn.apply(obj, args) const result = fn.apply(obj, args) const result = fn.apply(obj, args) Otherwise, return obj Object return result instanceof Object? result : obj }Copy the code
Es5 implements INHERITANCE from ES6 (parasitic composite inheritance)
- To create a
An empty object
.An empty object
The prototype link toThe parent class
theExplicit prototype
on An empty object
theconstructor
Point to theA subclass
- A subclass
Explicit prototype
Point to theAn empty object
// function inherit(Child, Parent) {// create a 'empty object', Const obj = object.create (Parent. Prototype) // constructor 'points to' subclass 'obj.construct = Child Prototype = obj} function Person(name) {this.name = name this.colors = ['red', 'blue', 'green'] } Person.prototype.sayName = function () { console.log(this.name) } function Student(name, Age) {person. call(this, name) this.age = age} Person) // Subclass methods must set student.prototype. sayAge = function () {console.log(this.age)} const stu = new after inheritance Student('violet', 20) console.log(stu) stu.sayName() stu.sayAge()Copy the code
Write a promise
Implementation constructor
promise
There are three statespending
.fulfilled
.rejected
promise
Can be caused bypending
Change forfulfilled
orpending
Change forrejected
The state is irreversible- create
promise
Instance, passing a functionexecutorFn
During the instance, this function will be called immediately to call theresolve
andreject
Pass to the consumer - If business is normal, the consumer will call
resolve()
Function to pass in the success result- in
resolve()
Function to change the state tofulfilled
And stores the successful value
- in
- If the business fails, the consumer calls
reject()
Function to pass in the cause of failure- in
reject()
Function to change the state torejected
And store the failure cause
- in
Class MyPromise {// Promise has three states pending, depressing, rejected static PENDING = 'pending' static FULFILLED = 'fulfilled' static REJECTED = 'rejected' constructor(executorFn) Value = undefined // Success value this.reason = undefined // failure cause // Const resolve = (value) => {if(this.state === mypromise.pending) {// Change the state to progressively this.state == this // Call this method const reject = (reason) => {if(this.state === =) Mypromise.pending) {// Modify the state to REJECTED this.state = myPromise.rejected // This. Reason = Reason}} try {// Execute the executorFn function immediately, passing resove and reject to the user executorFn(resolve, reject)} Catch (error) { Reject (error)}}} const p = new MyPromise((resolve, Reject) = > {resolve (' resolved ') / / reject (' had rejected ')}). The console log (p)Copy the code
Implement then methods
When calling THEN, the Promise instance object is in a state of PENDING, depressing, and REJECTED
PENDING
(wait state), the callback function needs to be collected before the state changes toFULFILLED
orREJECTED
, executes the callback functionFULFILLED
(Solved), you can directly execute the commandSuccessful callback function
FULFILLED
(Solved), you can directly execute the commandFailed callback function
- To support chained calls, the then method needs to return a new one
Promise instance object
Constructor (executorFn) {// omit content... This.state = myPromise.pending // Initialize PENDING this.onResolvedCallbacks = [] // Store successful callbacks this.onRejectedCallbacks = [] Const resolve = (value) => {if(this.state === mypromise.pending) {// Remove onResolvedCallbacks function executed in sequence in the enclosing onResolvedCallbacks. ForEach (fn = > fn ())}} / / this method is called is const failure reject = (reason) = > { If (this. State = = = MyPromise. PENDING) {this. OnRejectedCallbacks. ForEach (fn = > fn ())}} / / omitted content... } /** * @description then function * @param takes two functions as arguments, This is a big pity, onFulfilled */ then(onFulfilled, Ondepressing === 'function'? // This is a big pity! // This is a big pity === 'function'? onFulfilled : (v) => v onRejected = typeof onRejected === 'function' ? onRejected : (err) => {throw err} const p1 = new MyPromise(resolve, reject) => { In performing the if (this. State = = = MyPromise. PENDING) {/ / cache the success callback this. OnResolvedCallbacks. Push ((() = > {setTimeout () = > {try { const newValue = onFulfilled(this.value) resolve(newValue) // p1.value = newValue } catch (err) { reject(err) } }) }) // Cache failed callback enclosing onRejectedCallbacks. Push ((() = > {setTimeout () = > {try {const newReason = onRejected (enclosing a tiny) Resolve (newReason) // p1.reason = newReason} Catch (err) {reject(err)}})})} // Resolve status if(this.state === This is a big pity) {// Use setTimeout to simulate asynchronous, SetTimeout (() => {try {// Retrieve the stored success value const newValue = ondepressing (this.value) resolve(newValue)} catch (err) {reject(err)}})} if(this.state === myPromise.rejected) {// Use setTimeout to simulate asyncio, SetTimeout (() => {try {// Fetch the stored success value const newReason = onRejected(this.reason) resolve(newReason)} catch (err) { reject(err) } }) } }) return p1 } }Copy the code
Optimize THEN: Extract common parts
Then internal code above, there are parts of the code similar, can sit down to extract
// then method, This is a big pity. Then (onFulfilled, onRejected) {return MyPromise((forget, onFulfilled)); reject) => { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (val) => val onRejected = typeof onRejected === 'function' ? onRejected : (err) => { throw err } const asyncHander = (cb, CurrentResult) => {setTimeout(() => {try {const newResult = cb(currentResult) // Passed to the next resolve(newResult)} catch (error) {reject(error)}})} // This is a big pity. State === MyPromise. asyncHander(onFulfilled, If (this.state === myPromise.rejected) {asyncHander(onRejected, This.reason)} // State is PENDING; Cache the callback function if (this. State = = = MyPromise. PENDING) {this. OnFulfilledCallbacks. Push (() = > {asyncHander (onFulfilled, this.value) }) this.onRejectedCallbacks.push(() => { asyncHander(onRejected, this.reason) }) } }) }Copy the code
Implementing catch methods
Catch is a shortened version of then, where onRejected is accepted and only onRejected is processed
catch(onRejected) {
return this.then(null, onRejected)
}
Copy the code
Implement the resolve static method
Instantiate a Promise instance object and pass data to the Promise instance object. Resolve method
class MyPromise {
static resolve(result) {
return new MyPromise((resolve, reject) => {
resolve(result)
})
}
}
Copy the code
Implement the reject static method
Instantiate a Promise instance object, passing the reason to the Promise instance object. Reject
class MyPromise {
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
}
Copy the code
Implement the Race static method
- Receives an array containing the Promise instance
- Instantiate a
New Promise instance object
- In the new Promise instance object, traverse the array of Promise instances
- Takes an instance of a Promise and executes the promise instance
then
Method that returns as long as there is a complete state change (success or failure)
- Takes an instance of a Promise and executes the promise instance
- return
New Promise instance object
Class MyPromise {// Return static race(promiseList) {return new MyPromise((resolve, resolve)) reject) => { promiseList.forEach(p => { p.then(resolve, reject) }) }) } }Copy the code
Implement all static methods
-
Receives an array containing the Promise instance
-
Instantiate a new Promise instance object
-
In the new Promise instance object, traverse the array of Promise instances
- Takes an instance of a Promise and executes the promise instance
then
Method, which returns results on all successes and failed on one failure
- Takes an instance of a Promise and executes the promise instance
-
Returns the new Promise instance object
Class MyPromise {// Execute array all promises, all successes return result, one failure, Static all(arr) {return new MyPromise((resolve, resolve, reject) => { const result = [] let index = 0 let length = arr.length arr.forEach(p => { p.then(res => { result.push(res) If (index++ === leng-1) {resolve(result)}}). Catch (err => {reject(err)})})}}Copy the code