preface
Hello, I'm Lin Sanxin. Foundation is the premise of advanced. I shared 50 JS basic knowledge points and 50 JS advanced knowledge points in this rookie's notes over the past year
- 50 basic knowledge points of JavaScript encountered in work
- Ten thousand words summary "stay up late to summarize 50 advanced knowledge points of JS
Today, I will share with you the 56 JavaScript handwriting knowledge points in my notes
Note: This article does not contain algorithm problems
Interview test
1. Implement native AJAX requests
const ajax = { get(url, fn) { const xhr = new XMLHttpRequest() xhr.open('GET', url, true)// The third parameter is asynchronous or not xhr.onreadystatechange = function() { if (xhr.readyState === 4) { fn(xhr.responeText) } } xhr.send() }, post(url, data, fn) { const xhr = new XMLHttpRequest() xhr.open('POST', url, true) xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded') xhr.onreadystatechange = function () { if (xhr.readyState === 4) { fn(xhr.responeText) } } xhr.send(data) } }
2. Process of handwritten new
function myNew(fn, ...args) { const obj = {} obj.__proto__ = fn.prototype fn.apply(obj, args) return obj }
3. instanceof keyword
function instanceOf(father, child) { const fp = father.prototype var cp = child.__proto__ while (cp) { if (cp === fp) { return true } cp = cp.__proto__ } return false }
4. Implementation of anti shake function
function debounce(fn, delay = 500) { let timer; return function () { if (timer) { clearTimeout(timer) } const args = arguments timer = setTimeout(() => { fn.apply(this, args) // Change this to point to the object that debounce refers to }, delay) } }
5. Implement throttling function
function throttle(fn, delay = 200) { let flag = true return function () { if (!flag) return flag = false const args = arguments setTimeout(() => { fn.apply(this, args) flag = true }, delay) } }
6. Implementation of array de duplication
Topic Description: realize the de duplication of an array
// First: Map record function quchong1(arr) { const newArr = [] arr.reduce((pre, next) => { if (!pre[next]) { pre[next] = 1 newArr.push(next) } return pre }, {}) return newArr } // Second: Set de duplication function quchong2(arr) { return [...new Set(arr)] }
7. Implementing setInterval with setTimeout
Topic Description: setinterval is used to realize cyclic timing call. There may be some problems. Can settimeout be used to solve them
function mySetTimout(fn, delay) { let timer = null const interval = () => { fn() timer = setTimeout(interval, delay) } setTimeout(interval, delay) return { cancel: () => { clearTimeout(timer) } } } // test const { cancel } = mySetTimout(() => console.log(888), 1000) setTimeout(() => { cancel() }, 4000)
8. Implementing setTimeout with setInterval
No, I just want to make it difficult for you
function mySetInterval(fn, delay) { const timer = setInterval(() => { fn() clearInterval(timer) }, delay) } // test mySetInterval(() => console.log(888), 1000)
9. Implement a compose function
Title Description: achieve the following effects
function fn1(x) { return x + 1; } function fn2(x) { return x + 2; } function fn3(x) { return x + 3; } function fn4(x) { return x + 4; } const a = compose(fn1, fn2, fn3, fn4); console.log(a) console.log(a(1)); // 1+2+3+4=11
The implementation is as follows:
function compose(...fn) { if (fn.length === 0) return (num) => num if (fn.length === 1) return fn[0] return fn.reduce((pre, next) => { return (num) => { return next(pre(num)) } }) }
10. Implement a Coriolis function
Title Requirements:
const add = (a, b, c) => a + b + c; const a = currying(add, 1); console.log(a(2,3)) // 1 + 2 + 3=6
The implementation is as follows:
function currying(fn, ...args1) { // How many parameters to get fn const length = fn.length let allArgs = [...args1] const res = (...arg2) => { allArgs = [...allArgs, ...arg2] // If the length is equal, the execution result is returned if (allArgs.length === length) { return fn(...allArgs) } else { // Unequal continue return function return res } } return res } // Test: const add = (a, b, c) => a + b + c; const a = currying(add, 1); console.log(a(2,3))
11. Implement an LRU cache function
Title Description:
The implementation is as follows:
class LRUCache { constructor(size) { this.size = size this.cache = new Map() } get(key) { const hasKey = this.cache.has(key) if (hasKey) { const val = this.cache.get(key) this.cache.delete(key) this.cache.set(key, val) return val } else { return -1 } } put(key, val) { const hasKey = this.cache.has(key) if (hasKey) { this.cache.delete(key) } this.cache.set(key, val) if (this.cache.size > this.size) { this.cache.delete(this.cache.keys().next().value) } } }
12. Simple implementation of publish subscribe mode
Topic Description: implement a publish subscribe mode with the on emit once off method
class EventEmitter { constructor() { this.cache = {} } on(name, fn) { const tasks = this.cache[name] if (tasks) { this.cache[name].push(fn) } else { this.cache[name] = [fn] } } off(name, fn) { const tasks = this.cache[name] if (task) { const index = tasks.findIndex(item => item === fn) if (index >= 0) { this.cache[name].splice(index, 1) } } } emit(name, once = false, ...args) { // Make a copy. Prevent the callback from continuing on, resulting in an endless loop const tasks = this.cache[name].slice() if (tasks) { for (let fn of tasks) { fn(...args) } } if (once) { delete this.cache[name] } } once(name, ...args) { this.emit(name, true, ...args) } }
13. Implement JSON.parse
Title Description: realize JSON.parse
function parse (json) { return eval("(" + json + ")"); }
14. Convert DOM to tree structure object
Title Description:
<div> <span></span> <ul> <li></li> <li></li> </ul> </div> Place the top DOM Convert to the following tree structure object { tag: 'DIV', children: [ { tag: 'SPAN', children: [] }, { tag: 'UL', children: [ { tag: 'LI', children: [] }, { tag: 'LI', children: [] } ] } ] }
The implementation is as follows:
function dom2tree(dom) { const obj = {} obj.tag = dom.tagName obj.children = [] dom.childNodes.forEach(child => obj.children.push(dom2tree(child))) return obj }
15. Convert tree structure to DOM
Title Description:
{ tag: 'DIV', children: [ { tag: 'SPAN', children: [] }, { tag: 'UL', children: [ { tag: 'LI', children: [] }, { tag: 'LI', children: [] } ] } ] } Convert the tree structure object above to the tree structure object below DOM <div> <span></span> <ul> <li></li> <li></li> </ul> </div>
The implementation is as follows:
// Real rendering function function _render(vnode) { // If it is a numeric type, convert it to a string if (typeof vnode === "number") { vnode = String(vnode); } // The string type is the text node directly if (typeof vnode === "string") { return document.createTextNode(vnode); } // Normal DOM const dom = document.createElement(vnode.tag); if (vnode.attrs) { // traversal attributes Object.keys(vnode.attrs).forEach((key) => { const value = vnode.attrs[key]; dom.setAttribute(key, value); }); } // Recursive operation of subarray vnode.children.forEach((child) => dom.appendChild(_render(child))); return dom; }
16. Judge whether an object has a ring reference
Topic Description: verify whether an object has a ring reference
var obj = { a: { c: [ 1, 2 ] }, b: 1 } obj.a.c.d = obj console.log(cycleDetector(obj)) // true
Implementation idea: use an array to store each traversed object. The next time you find the existence in the array, it indicates the ring reference
function cycleDetector(obj) { const arr = [obj] let flag = false function cycle(o) { const keys = Object.keys(o) for (const key of keys) { const temp = o[key] if (typeof temp === 'object' && temp !== null) { if (arr.indexOf(temp) >= 0) { flag = true return } arr.push(temp) cycle(temp) } } } cycle(obj) return flag }
17. Calculate the number of layers of an object
Title Description: give you an object and count its layers
const obj = { a: { b: [1] }, c: { d: { e: { f: 1 } } } } console.log(loopGetLevel(obj)) // 4
The implementation is as follows:
function loopGetLevel(obj) { var res = 1; function computedLevel(obj, level) { var level = level ? level : 0; if (typeof obj === 'object') { for (var key in obj) { if (typeof obj[key] === 'object') { computedLevel(obj[key], level + 1); } else { res = level + 1 > res ? level + 1 : res; } } } else { res = level > res ? level : res; } } computedLevel(obj) return res }
18. Flattening of objects
Title Description:
const obj = { a: { b: 1, c: 2, d: }, b: [1, 3, ], c: 3 } flatten(obj) The results are returned as follows // { // 'a.b': 1, // 'a.c': 2, // 'a.d.e': 5, // 'b[0]': 1, // 'b[1]': 3, // 'b[2].a': 2, // 'b[2].b': 3 // c: 3 // }
The implementation is as follows:
const isObject = (val) => typeof val === "object" && val !== null function flatten(obj) { if (!isObject(obj)) return const res = {} const dfs = (cur, prefix) => { if (isObject(cur)) { if (Array.isArray(cur)) { cur.forEach((item, index) => { dfs(item, `$[$]`) }) } else { for(let key in cur) { dfs(cur[key], `$$$`) } } } else { res[prefix] = cur } } dfs(obj, '') return res } // test console.log(flatten(obj))
19. Implementation (a = = 1 & & A = = 2 & & A = = 3) is true
Title Description: the implementation (a = = 1 & & A = = 2 & & A = = 3) is true
// The first method var a = { i: 1, toString: function () { return a.i++; } } console.log(a == 1 && a == 2 && a == 3) // true // The second method var a = [1, 2, 3]; a.join = a.shift; console.log(a == 1 && a == 2 && a == 3); // true // The third method var val = 0; Object.defineProperty(window, 'a', { get: function () { return ++val; } }); console.log(a == 1 && a == 2 && a == 3) // true
20. Implement Promise scheduler to limit concurrency
Title Description: JS implements an asynchronous Scheduler with concurrency constraints, which ensures that there are at most two tasks running at the same time
addTask(1000,"1"); addTask(500,"2"); addTask(300,"3"); addTask(400,"4"); The output order is: 2 3 1 4 Complete execution process of the whole: At the beginning, 1 and 2 tasks are executed 500ms When, task 2 is completed, output 2, and task 3 starts to execute 800ms When, task 3 is completed, output 3, and task 4 begins to execute 1000ms When 1 task is executed, 1 is output, and only 4 tasks are left to execute 1200ms When the task is completed, output 4
The implementation is as follows:
class Scheduler { constructor(limit) { this.queue = [] this.limit = limit this.count = 0 } add(time, order) { const promiseCreator = () => { return new Promise((resolve, reject) => { setTimeout(() => { console.log(order) resolve() }, time) }) } this.queue.push(promiseCreator) } taskStart() { for(let i = 0; i < this.limit; i++) { this.request() } } request() { if (!this.queue.length || this.count >= this.limit) return this.count++ this.queue.shift()().then(() => { this.count-- this.request() }) } } // test const scheduler = new Scheduler(2); const addTask = (time, order) => { scheduler.add(time, order); }; addTask(1000, "1"); addTask(500, "2"); addTask(300, "3"); addTask(400, "4"); scheduler.taskStart();
21. Implement lazyMan function
Title Description:
Implement a LazyMan,Can be called as follows: LazyMan("Hank")output: Hi! This is Hank! LazyMan("Hank").sleep(10).eat("dinner")output Hi! This is Hank! //Wait 10 seconds Wake up after 10 Eat dinner~ LazyMan("Hank").eat("dinner").eat("supper")output Hi This is Hank! Eat dinner~ Eat supper~ LazyMan("Hank").eat("supper").sleepFirst(5)output //Wait 5 seconds Wake up after 5 Hi This is Hank! Eat supper
The implementation is as follows:
class _LazyMan { constructor(name) { this.tasks = [] const task = () => { console.log(`Hi! This is $`) this.next() } this.tasks.push(task) setTimeout(() => { this.next() }, 0) } next() { const task = this.tasks.shift() task && task() } sleep(time) { this.sleepWrapper(time, false) return this } sleepFirst(time) { this.sleepWrapper(time, true) return this } sleepWrapper(time, first) { const task = () => { setTimeout(() => { console.log(`Wake up after $`) this.next() }, time * 1000) } if (first) { this.tasks.unshift(task) } else { this.tasks.push(task) } } eat(food) { const task = () => { console.log(`Eat $`); this.next(); }; this.tasks.push(task); return this; } } // test const lazyMan = (name) => new _LazyMan(name) lazyMan('Hank').sleep(1).eat('dinner') lazyMan('Hank').eat('dinner').eat('supper') lazyMan('Hank').eat('supper').sleepFirst(5)
22. Implement the add function
Title Description: implement an add method to make the calculation results meet the following expectations:
- add(1)(2)(3)()=6
- add(1,2,3)(4)()=10
function add(...args1) { let allArgs = [...args1] function fn(...args2) { if (!args2.length) return fn.toString() allArgs = [...allArgs, ...args2] return fn } fn.toString = function () { return allArgs.reduce((pre, next) => pre + next) } return fn } // test console.log(add(1)(2)(3)()) console.log(add(1, 2)(3)())
23. Achieve a qualified deep copy
I recommend this article: The deep copy has these five stages. Are you just a bronze stage? Still want a raise?
24. Implement Promise
I recommend this article: Read it, handwritten Promise principle, the most easy to understand version!!! [read: 1.3w, like: 460]
25. Implement async/await
I recommend this article: 7 pictures, async/await principle that can be done in 20 minutes! Why did it take so long? [Reading: 2.15w, likes: 460]
Array chapter
Define a test array
const players = [ { name: 'Kobe', num: 24 }, { name: 'James', num: 23 }, { name: 'Paul', num: 3 }, { name: 'Wei Shao', num: 0 }, { name: 'Durant', num: 35 } ]
26,forEach
Parameter represents meaning
- Item: traversal item
- Index: the index of the traversal item
- arr: array itself
Array.prototype.sx_forEach = function (callback) { for (let i = 0; i < this.length; i++) { callback(this[i], i, this) } } players.sx_forEach((item, index, arr) => { console.log(item, index) }) // 0 // 1 // 2 // 3 // 4
27,map
Parameter represents meaning
- Item: traversal item
- Index: the index of the traversal item
- arr: array itself
Array.prototype.sx_map = function (callback) { const res = [] for (let i = 0; i < this.length; i++) { res.push(callback(this[i], i, this)) } return res } console.log(players.sx_map((item, index) => `$--$--$`)) // ['Kobe -- 24 -- 0', 'James -- 23 -- 1', 'Paul -- 3 -- 2', 'Wesson -- 0 -- 3', 'Durant -- 35 -- 4']
28,filter
Parameter represents meaning
- Item: traversal item
- Index: the index of the traversal item
- arr: array itself
Array.prototype.sx_filter = function (callback) { const res = [] for (let i = 0; i < this.length; i++) { callback(this[i], i, this) && res.push(this[i]) } return res } console.log(players.sx_filter(item => item.num >= 23)) // [ // , // , // // ]
29,every
Parameter represents meaning
- Item: traversal item
- Index: the index of the traversal item
- arr: array itself
Array.prototype.sx_every = function (callback) { let flag = true for (let i = 0; i < this.length; i++) { flag = callback(this[i], i, this) if (!flag) break } return flag } console.log(players.sx_every(item => item.num >= 23)) // false console.log(players.sx_every(item => item.num >= 0)) // true
30,some
Parameter represents meaning
- Item: traversal item
- Index: the index of the traversal item
- arr: array itself
Array.prototype.sx_some = function (callback) { let flag = false for (let i = 0; i < this.length; i++) { flag = callback(this[i], i, this) if (flag) break } return flag } console.log(players.sx_some(item => item.num >= 23)) // true console.log(players.sx_some(item => item.num >= 50)) // false
31,reduce
Parameter represents meaning
- pre: previous item
- Next: next
- Index: current index
- arr: array itself
Array.prototype.sx_reduce = function (callback, initValue) { let start = 0, pre if (initValue) { pre = initValue } else { pre = this[0] start = 1 } for (let i = start; i < this.length; i++) { pre = callback(pre, this[i], i, this) } return pre } // Calculate the sum of all num const sum = players.sx_reduce((pre, next) => { return pre + next.num }, 0) console.log(sum) // 85
32,findIndex
Parameter represents meaning
- Item: traversal item
- Index: the index of the traversal item
- arr: array itself
Array.prototype.sx_findIndex = function (callback) { for (let i = 0; i < this.length; i++) { if (callback(this[i], i, this)) { return i } } return -1 } console.log(players.sx_findIndex(item => item.name === 'Kobe')) // 0 console.log(players.sx_findIndex(item => item.name === 'Anthony')) // -1
33,find
Parameter represents meaning
- Item: traversal item
- Index: the index of the traversal item
- arr: array itself
Array.prototype.sx_find = function (callback) { for (let i = 0; i < this.length; i++) { if (callback(this[i], i, this)) { return this[i] } } return undefined } console.log(players.sx_find(item => item.name === 'Kobe')) // console.log(players.sx_find(item => item.name === 'Anthony')) // undefined
34,fill
Usage: fill array
Parameter represents meaning
- initValue: filled value
- Start: start to fill the index. The default value is 0
- End: end the index filling. The default is length
Array.prototype.sx_fill = function (value, start = 0, end) { end = end || this.length for (let i = start; i < end; i++) { this[i] = value } return this } console.log(players.sx_fill('Lin Sanxin', 1, 3)) // [ // , // 'Lin Sanxin', // 'Lin Sanxin', // 'Lin Sanxin', // // ]
35,includes
Usage: find elements and return true; otherwise, return false to find NaN
Array.prototype.sx_includes = function (value, start = 0) { if (start < 0) start = this.length + start const isNaN = Number.isNaN(value) for (let i = start; i < this.length; i++) { if (this[i] === value || Number.isNaN(this[i]) === isNaN) { return true } } return false } console.log([1, 2, 3].sx_includes(2)) // true console.log([1, 2, 3, NaN].sx_includes(NaN)) // true console.log([1, 2, 3].sx_includes(1, 1)) // false
36,join
Usage: spell the array into a string with a separator. The separator defaults to,
Array.prototype.sx_join = function (s = ',') { let str = '' for(let i = 0; i < this.length; i++) { str = i === 0 ? `$$` : `$$$` } return str } console.log([1, 2, 3].sx_join()) // 1,2,3 console.log([1, 2, 3].sx_join('*')) // 1*2*3
37,flat
Array.prototype.sx_flat = function () { let arr = this while (arr.some(item => Array.isArray(item))) { arr = [].concat(...arr) } return arr } const testArr = [1, [2, 3, [4, 5]], [8, 9]] console.log(testArr.sx_flat()) // [1, 2, 3, 4, 5, 8, 9]
38,splice
difficulty
- Comparison of interception length and replacement length, different cases
Array.prototype.sx_splice = function (start, length, ...values) { length = start + length > this.length - 1 ? this.length - start : length const res = [], tempArr = [...this] for (let i = start; i < start + values.length; i++) { this[i] = values[i - start] } if (values.length < length) { const cha = length - values.length for (let i = start + values.length; i < tempArr.length; i++) { this[i] = tempArr[i + cha] } this.length = this.length - cha } if (values.length > length) { for (let i = start + length; i < tempArr.length; i++) { this.push(tempArr[i]) } } for (let i = start; i < start + length; i++) { res.push(tempArr[i]) } return res }
Object article
Define a test object
const obj = { name: 'Lin Sanxin', age: 22, gender: 'male' }
39,entries
Usage: convert the object into an array of key value pairs
Object.prototype.sx_entries = function (obj) { const res = [] for (let key in obj) { obj.hasOwnProperty(key) && res.push([key, obj[key]]) } return res } console.log(Object.sx_entries(obj)) // [['name ',' Lin Sanxin '], ['age', 22], ['gender ',' male ']]
40,fromEntries
Use: Contrary to entries, convert the key value pair array into an object
Object.prototype.sx_fromEntries = function (arr) { const obj = {} for (let i = 0; i < arr.length; i++) { const [key, value] = arr[i] obj[key] = value } return obj } console.log(Object.sx_fromEntries([['name', 'Lin Sanxin'], ['age', 22], ['gender', 'male']])) //
41,keys
Usage: convert the key of the object into an array collection
Object.prototype.sx_keys = function (obj) { const keys = [] for (let key in obj) { obj.hasOwnProperty(key) && res.push(key) } return keys } console.log(Object.keys(obj)) // [ 'name', 'age', 'gender' ]
42,values
Usage: convert all values of an object into an array collection
Object.prototype.sx_values = function (obj) { const values = [] for (let key in obj) { obj.hasOwnProperty(key) && values.push(obj[key]) } return values } console.log(Object.sx_values(obj)) // ['Lin Sanxin', 22, 'male']
43,instanceOf
Use: A instanceOf B to judge whether A passes through the prototype chain of B
function instanceOf(father, child) { const fp = father.prototype var cp = child.__proto__ while (cp) { if (cp === fp) { return true } cp = cp.__proto__ } return false } function Person(name) { this.name = name } const sx = new Person('Lin Sanxin') console.log(instanceOf(Person, sx)) // true console.log(instanceOf(Person, sx2)) // false
44,is
Use: Object.is(a, b) to judge whether a is equal to B
Object.prototype.sx_is = function (x, y) { if (x === y) { // Prevent - 0 and + 0 return x !== 0 || 1 / x === 1 / y } // Prevent NaN return x !== x && y !== y } const a = { name: 'Lin Sanxin' } const b = a const c = { name: 'Lin Sanxin' } console.log(Object.sx_is(a, b)) // true console.log(Object.sx_is(a, c)) // false
45,Object.assign
difficulty
- assign receives multiple objects and combines them into one object
- If these objects have duplicate name attributes, the later object attribute values shall prevail
- assign returns an object, which = = = the first object
Object.prototype.sx_assign = function (target, ...args) { if (target === null || target === undefined) { throw new TypeError('Cannot convert undefined or null to object') } target = Object(target) for (let nextObj of args) { for (let key in nextObj) { nextObj.hasOwnProperty(key) && (target[key] = nextObj[key]) } } return target } const testa = { name: 'Lin Sanxin' } const testb = { name: 'sunshine_lin', age: 22 } const testc = { age: 18, gender: 'male' } const testd = Object.sx_assign(testa, testb, testc) console.log(testd) // console.log(testa === testd) // true
Function
46,call
Function.prototype.sx_call = function (obj, ...args) { obj = obj || window // Symbol is unique to prevent duplicate key names const fn = Symbol() obj[fn] = this // Execute, return execution value return obj[fn](...args) } const testobj = { name: 'Lin Sanxin', testFn(age) { console.log(`$$Years old`) } } const testobj2 = { name: 'sunshine_lin' } testobj.testFn.sx_call(testobj2, 22) // sunshine_ Lin is 22 years old
47,apply
Function.prototype.sx_apply = function (obj, args) { obj = obj || window // Symbol is unique to prevent duplicate key names const fn = Symbol() obj[fn] = this // Execute, return execution value return obj[fn](...args) } const testobj = { name: 'Lin Sanxin', testFn(age) { console.log(`$$Years old`) } } const testobj2 = { name: 'sunshine_lin' } testobj.testFn.sx_apply(testobj2, [22]) // sunshine_ Lin is 22 years old
48,Function.prototype.bind
Difficulties:
- bind returns a function, not an execution result
- The function returned by bind is used as a constructor. What should I do
Function.prototype.sx_bind = function (obj, ...args) { obj = obj || window // Symbol is unique to prevent duplicate key names const fn = Symbol() obj[fn] = this const _this = this const res = function (...innerArgs) { console.log(this, _this) if (this instanceof _this) { this[fn] = _this this[fn](...[...args, ...innerArgs]) delete this[fn] } else { obj[fn](...[...args, ...innerArgs]) delete obj[fn] } } res.prototype = Object.create(this.prototype) return res }
String article
49,slice
Parameter represents meaning
- Start: the character index to start intercepting (including this character)
- End: end the intercepted character index (excluding this character)
Attention - Start > end: returns an empty string
- Start < 0: start = array length + start
String.prototype.sx_slice = function (start = 0, end) { start = start < 0 ? this.length + start : start end = !end && end !== 0 ? this.length : end if (start >= end) return '' let str = '' for (let i = start; i < end; i++) { str += this[i] } return str } console.log(str.sx_slice(2)) // nshine_lin console.log(str.sx_slice(-2)) // in console.log(str.sx_slice(-9, 10)) // shine_l console.log(str.sx_slice(5, 1)) // ''
50,substr
Parameter represents meaning
- Start: the character index to start intercepting (including this character)
- Length: intercepted length
Attention - Start < 0: start = array length + start
- The length exceeds the interception range and needs to be processed
- Length < 0: returns an empty string
String.prototype.sx_substr = function (start = 0, length) { if (length < 0) return '' start = start < 0 ? this.length + start : start length = (!length && length !== 0) || length > this.length - start ? this.length : start + length let str = '' for (let i = start; i < length; i++) { str += this[i] } return str } console.log(str.sx_substr(3)) // shine_lin console.log(str.sx_substr(3, 3)) // shi console.log(str.sx_substr(5, 300)) // ine_lin
51,substring
The function is roughly the same as slice
Differences
- Start > end: swap values
String.prototype.sx_sunstring = function (start = 0, end) { start = start < 0 ? this.length + start : start end = !end && end !== 0 ? this.length : end if (start >= end) [start, end] = [end, start] let str = '' for (let i = start; i < end; i++) { str += this[i] } return str } console.log(str.sx_sunstring(2)) // nshine_lin console.log(str.sx_sunstring(-2)) // in console.log(str.sx_sunstring(-9, 10)) // shine_l console.log(str.sx_sunstring(5, 1)) // unsh
Promise
52,all
- Receive a Promise array. If there are non Promise items in the array, this item will be regarded as successful
- If all promises are successful, the success result array is returned
- If a Promise fails, this failure result is returned
function all(promises) { const result = [] let count = 0 return new MyPromise((resolve, reject) => { const addData = (index, value) => { result[index] = value count++ if (count === promises.length) resolve(result) } promises.forEach((promise, index) => { if (promise instanceof MyPromise) { promise.then(res => { addData(index, res) }, err => reject(err)) } else { addData(index, promise) } }) }) }
53,race
- Receive a Promise array. If there are non Promise items in the array, this item will be regarded as successful
- Whichever Promise gets the fastest result will return that result, regardless of success or failure
function race(promises) { return new MyPromise((resolve, reject) => { promises.forEach(promise => { if (promise instanceof MyPromise) { promise.then(res => { resolve(res) }, err => { reject(err) }) } else { resolve(promise) } }) }) }
54,allSettled
- Receive a Promise array. If there are non Promise items in the array, this item will be regarded as successful
- Combine the results of each Promise into an array and return
function allSettled(promises) { return new Promise((resolve, reject) => { const res = [] let count = 0 const addData = (status, value, i) => { res[i] = { status, value } count++ if (count === promises.length) { resolve(res) } } promises.forEach((promise, i) => { if (promise instanceof MyPromise) { promise.then(res => { addData('fulfilled', res, i) }, err => { addData('rejected', err, i) }) } else { addData('fulfilled', promise, i) } }) }) }
55,any
any is the opposite of all
- Receive a Promise array. If there are non Promise items in the array, this item will be regarded as successful
- If a Promise succeeds, the success result is returned
- If all promises fail, an error is reported
function any(promises) { return new Promise((resolve, reject) => { let count = 0 promises.forEach((promise) => { promise.then(val => { resolve(val) }, err => { count++ if (count === promises.length) { reject(new AggregateError('All promises were rejected')) } }) }) }) } }
56,finally
- Receive a callback function with no parameters
- finally is executed regardless of the success or failure status
Promise.prototype.finally = function(callback) { return this.then(res => { callback() return res }, err => { callback() throw err }) }
epilogue
If you think this article is of little help to you, give a praise and encourage Lin Sanxin, ha ha. Or you can join my fishing group. If you want to join the learning group and fishing group, I will regularly broadcast the simulated interview to answer questions and solve doubts