Stay up late to sort out 56 advanced handwriting knowledge points of JavaScript

preface Hello, I'm Lin Sanxin. Foundation is ...
preface
Interview test
Array chapter
Object article
Function
String article
Promise
epilogue

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

3 November 2021, 19:41 | Views: 4936

Add new comment

For adding a comment, please log in
or create account

0 comments