handwrittenPromise
pending
Closure implementationonce
function once(fn) {
let done = false;
return function () {
if(! done) { done =true;
fn.apply(this.arguments); }}; }const pay = once(function (money) {
console.log(` selections:${money}`);
});
pay(100);
pay(100);
Copy the code
Throttling function
Only one function is allowed to be executed within the interval; Such functions are function throttles;
Solution a:
function throttle(func ,delay = 500) {
let timer = null;
return function () {
let context = this
if(! timer){ timer =setTimeout(() = > {
func.apply(context, arguments)
timer = null
}, delay)
}
}
}
Copy the code
Scheme 2:
function throttle(func ,delay = 500) {
let activeTime = 0;
return function () {
let context = this
let current = Date.now();
if(current - activeTime > delay) {
func.apply(context, arguments)
activeTime = Date.now(); }}}Copy the code
Image stabilization function
If a program is executed repeatedly within a certain time interval, the program execution time is reset.
function debounce(fn, delay = 500) {
let timer = null;
return function () {
let context = this
clearTimeout(timer)
timer = setTimeout(() = > {
fn.apply(context, arguments) }, delay); }}Copy the code
implementationmap
const map = (array, fn) = > {
let results = []
for (let item of array) {
results.push(fn(item))
}
return results
}
Copy the code
implementationevery
const every = (array, fn) = > {
let result = true
for (let value of array) {
result = fn(value)
if(! result) {break}}return result
}
Copy the code
implementationsome
const some = (array, fn) = > {
let result = false
for (let value of array) {
result = fn(value)
if (result) {
break}}return result
}
Copy the code
Simulation of the lodashmemoize
Method implementation
function memoize (fn) {
let cache = {} // Parameter as key, result as value
return function () {
let key = JSON.stringify(arguments) // take a pseudo-array string as an argument
cache[key] = cache[key] || fn.apply(fn, arguments)
return cache[key]
}
}
Copy the code
It’s OK to try
function getArea (r) {
console.log(r);
return Math.PI**r
}
let getAreaWithMemory = memoize(getArea)
console.log(getAreaWithMemory(4)) // Only 4 is printed, which is cached
console.log(getAreaWithMemory(4))
console.log(getAreaWithMemory(4))
Copy the code
Implement function combinationcompose
Simulate the flow method in LoDash
const reverse = arr= > arr.reverse();
const first = arr= > arr[0];
const toUpper = s= > s.toUpperCase();
const compose = (. fns) = > {
return function (value) {
return fns.reduce((acc, fn) = > {
return fn(acc)
}, value)
}
}
const a = compose(reverse, first, toUpper)
console.log(a(['one'.'two'.'three']));
Copy the code
Use the arrow function shorthand
const compose = (. fns) = > value= > fns.reduce((acc, fn) = > fn(acc), value);
Copy the code
Analog implementationlodash
In thecurry
methods
- Corrification allows us to pass in fewer arguments to a function and get a new function that has memorized some of the fixed arguments
- This is a “cache” of function parameters, using closures
- Make functions more flexible and smaller in granularity
- You can convert multivariate functions into unary functions, and you can combine functions to produce powerful functions
function getSum(a, b, c) {
return a + b + c
}
function curry (func) {
return function curriedFn (. args) {
// Determine the number of arguments and parameters
if (args.length < func.length) { // method name. length => Get the number of parameters
return function () { // Arguments
// recursive call
returncurriedFn(... args.concat(Array.from(arguments)))}}// Execute when the number of arguments and parameters is equal
returnfunc(... args) } }const curried = curry(getSum)
// console.log(curried(1, 2, 3))
// console.log(curried(1, 2)(3))
console.log(curried(1) (2) (3))
Copy the code
Writing anew
operation
- The first kind of
function _new(fn, ... args) {
let obj = Object.create(fn.prototype)
fn.apply(obj, args)
return obj
}
Copy the code
- The second way to write it
function New(Fn, ... args) {
Create an empty object obj
const obj = {};
// 2. Point the __proto__ attribute of the object to the prototype of the constructor
obj.__proto__ = Fn.prototype;
// 3. Bind the execution context (this) to the newly created object
const result = Fn.apply(obj, args);
// 4. If the constructor returns a value of "reference type", return it. Otherwise return the object created above
return result instanceof Object ? result : obj;
}
Copy the code
bind,apply,call
implementation
- Bind is poorly implemented and needs to be perfected in the case of new
Function.prototype.bind2 = function (context) {
var self = this;
// Get the bind2 function from the second argument to the last argument
var args = Array.prototype.slice.call(arguments.1);
return function () {
// Arguments refer to the arguments passed in by the function returned by bind
var bindArgs = Array.prototype.slice.call(arguments); self.apply(context, args.concat(bindArgs)); }}Copy the code
apply
andcall
The implementation of the
Function.prototype.apply2 = function (context, array) {
context = context || window
context.fn = this;
const result = context.fn(array)
delete context.fn
return result
}
let obj = {
value: 2.test() {console.log(this.value)}
}
function test () {
console.log(this.value)
}
test.apply2(obj);
Copy the code
var
implementationlet
Block-level scoping characteristics
Since function arguments are passed by value, the current value of the index variable is copied to parameter I, and a closure is created inside the timer1 function that accesses variable I and returns different values
for (var index = 0; index < 5; index++) {
(function timer1(i) {
console.log(i);
})(index);
}
Copy the code
implementationreduce
Array.prototype.myReduce = function (func, initialValue) {
const arr = this
let base = typeof initialValue === 'undefined' ? arr[0] : initialValue;
const startIndex = typeof initialValue === 'undefined' ? 1 : 0;
arr.slice(startIndex).forEach(function (val, index) {
base = func(base, val, index + startIndex, arr)
})
return base
}
Copy the code
withreduce
implementationmap
if (!Array.prototype.mapUsingReduce) {
Array.prototype.mapUsingReduce = function (callback, thisArg) {
return this.reduce(function (accumulator, currentValue, currentIndex, sourceArray) {
accumulator[currentIndex] = callback.call(thisArg, currentValue, currentIndex, sourceArray)
returnaccumulator; }}}, [])const resp = [1.2.3].mapUsingReduce((currentValue, index, array) = > currentValue + index)
Copy the code
withreduce
implementationgroupBy
function groupBy(arr, property) {
return arr.reduce((data, item) = > {
const key = item[property];
if(! data[key]) { data[key] = []; } data[key].push(item);return data;
}, {});
}
Copy the code
implementationdomToJson
const dom = document.getElementById('wrapper')
function dom2Json(rootDom) {
const obj = {}
obj.tag = rootDom.tagName;
obj.className = rootDom.className;
obj.children = handleChildren(rootDom)
return obj;
}
// recursive processing
function handleChildren(rootDom) {
const result = [];
const childs = rootDom.children;
if(! childs || childs.length ===0) {
return result;
}
for (const child of childs) {
const obj = {}
obj.tag = child.tagName;
obj.className = child.className;
obj.children = handleChildren(child);
result.push(obj);
}
return result;
}
Copy the code
Implementing priority queuesPriorityQueue
Element attribute: priority
Methods: Add, out
function PriorityQueue() {
let queue = []
this.add = (item) = > {
if (queue.length === 0) {
queue.push(item)
} else {
for (let i = 0; i < queue.length; i++) {
const element = queue[i];
if (element < item) {
queue.splice(i, 0, item) // Perform queue jumping
return; // Terminate the function} } queue.push(item); }};this.out = () = > {
return queue.shift()
}
this.print = () = > {
returnqueue; }}const queue = new PriorityQueue()
Copy the code
Const arr =,0,0,1,0,0,0,0,0,1,0,0 [1];
Thinking is important!
Replace the 0 with 1, but the 1 and the 1 can’t be next to each other before.
const arr = [1.0.0.1.0.0.0.1.0.0];
const foo = (arr, n = 3) = > {
let count = 0;
const tempArr = arr.join(' ').split(1);
tempArr.forEach((item) = > {
if (item.length >= 3) {
const arrLen = arr.length;
count += Math.trunc(item.length / 2);
// Handle both ends of the array separately
if (arr[0= = =0 && arr[1= = =0 || arr[arrLen - 1= = =0 && arr[arrLen - 2= = =0) {
count += 1; }}})return count === n
};
Copy the code
The number array is sorted by the size of the trailing digit
const sort = (arr) = > {
arr.sort((a, b) = > a % 10 - b % 10)}Copy the code