分享10个面试题会经常出现的 JS 手写函数代码,你都会写吗?

共 7319字,需浏览 15分钟

 ·

2022-01-20 02:51


英文 | https://medium.com/@cookbug/10-common-front-end-handwriting-functions-do-you-know-all-of-them-9deb1ffb922d

翻译 | 杨小爱


只有万丈高楼平地起,才能永远立于不败之地。
今天给大家分享 10 个常用的 JavaScript 手写功能,重要的地方已经注释了。有些是从别人那里看来的,有些是我自己写的。如果有任何错误,请纠正我。在此,非常感谢。
1、防抖
function debounce(fn, delay) { let timer return function (…args) { if (timer) { clearTimeout(timer) } timer = setTimeout(() => { fn.apply(this, args) }, delay) }}// testfunction task() { console.log(‘run task’)}const debounceTask = debounce(task, 1000)window.addEventListener(‘scroll’, debounceTask)

2、节流

function throttle(fn, delay) { let last = 0 // Last trigger time return (…args) => { const now = Date.now() if (now-last> delay) { last = now fn.apply(this, args) } }}// testfunction task() { console.log(‘run task’)}const throttleTask = throttle(task, 1000)window.addEventListener(‘scroll’, throttleTask)

3、深拷贝

function deepClone(obj, cache = new WeakMap()) { if (typeof obj !==’object’) return obj if (obj === null) return obj if (cache.get(obj)) return cache.get(obj) // Prevent circular references, the program enters an infinite loop if (obj instanceof Date) return new Date(obj) if (obj instanceof RegExp) return new RegExp(obj)
// Find the constructor on the owning prototype, and the constructor on the owning prototype points to the constructor of the current object let cloneObj = new obj.constructor() cache.set(obj, cloneObj) // Cache copied objects, used to handle circular references for (let key in obj) { if (obj.hasOwnProperty(key)) { cloneObj[key] = deepClone(obj[key], cache) // recursive copy } } return cloneObj}// testconst obj = {name:’Jack’, address: {x: 100, y: 200}}obj.a = obj // circular referenceconst newObj = deepClone(obj)console.log(newObj.address === obj.address) // false

4、Promise 的实现

class MyPromise { constructor(executor) {// executor executor this.status =’pending’ // waiting status this.value = null // parameter of success or failure this.fulfilledCallbacks = [] // Successful function queue this.rejectedCallbacks = [] // Failed function queue const that = this function resolve(value) {// successful method if (that.status ===’pending’) { that.status =’resolved’ that.value = value that.fulfilledCallbacks.forEach(myFn => myFn(that.value)) //Execute callback method } } function reject(value) {//Failed method if (that.status ===’pending’) { that.status =’rejected’ that.value = value that.rejectedCallbacks.forEach(myFn => myFn(that.value)) //Execute callback method } } try { executor(resolve, reject) } catch (err) { reject(err) } } then(onFulfilled, onRejected) { if (this.status ===’pending’) { // Waiting state, add the callback function to the successful function queue this.fulfilledCallbacks.push(() => { onFulfilled(this.value) }) // Waiting state, add the callback function to the failed function queue this.rejectedCallbacks.push(() => { onRejected(this.value) }) } if (this.status ===’resolved’) {// support synchronous call console.log(‘this’, this) onFulfilled(this.value) } if (this.status ===’rejected’) {// Support synchronous call onRejected(this.value) } }}// testfunction fn() { return new MyPromise((resolve, reject) => { setTimeout(() => { if(Math.random()> 0.6) { resolve(1) } else { reject(2) } }, 1000) })}fn().then( res => { console.log(‘res’, res) // res 1 }, err => { console.log(‘err’, err) // err 2 })
5、异步控制并发数
function limitRequest(urls = [], limit = 3) { return new Promise((resolve, reject) => { const len = urls.length let count = 0// Start limit tasks simultaneously while (limit> 0) { start() limit -= 1 }function start() { const url = urls.shift() // Take the first task from the array if (url) { axios.post(url).finally(() => { if (count == len-1) { // The last task is completed resolve() } else { // After completion, start the next task count++ start() } }) } }})}// testlimitRequest([‘http://xxa','http://xxb','http://xxc','http://xxd','http://xxe'])
6、ES5继承(寄生组合继承)
function Parent(name) { this.name = name}Parent.prototype.eat = function () { console.log(this.name + ‘is eating’)}function Child(name, age) { Parent.call(this, name) this.age = age}Child.prototype = Object.create(Parent.prototype)Child.prototype.contructor = ChildChild.prototype.study = function () { console.log(this.name + ‘is studying’)}// testlet child = new Child(‘xiaoming’, 16)console.log(child.name) // xiaomingchild.eat() // xiaoming is eatingchild.study() // xiaoming is studying

7、数组排序

//sort// Sort the numbers, abbreviatedconst arr = [3, 2, 4, 1, 5]arr.sort((a, b) => a-b)console.log(arr) // [1, 2, 3, 4, 5]// Sort the letters, abbreviatedconst arr = [‘b’,’c’,’a’,’e’,’d’]arr.sort()console.log(arr) // [‘a’,’b’,’c’,’d’,’e’]
//Bubble Sortfunction bubbleSort(arr) { let len = arr.length for (let i = 0; i <len-1; i++) { // Starting from the first element, compare two adjacent elements, exchange positions if the former is bigger for (let j = 0; j <len-1-i; j++) { if (arr[j]> arr[j + 1]) { let num = arr[j] arr[j] = arr[j + 1] arr[j + 1] = num } } // At the end of each traversal, a maximum value can be found and placed at the end of the array } return arr}//testconsole.log(bubbleSort([2, 3, 1, 5, 4])) // [1, 2, 3, 4, 5]

8、阵列去重

设置重复数据删除
cosnt newArr = […new Set(arr)]

Array.from 去重

const newArr = Array.from(new Set(arr))

重复数据删除索引

function resetArr(arr) { let res = [] arr.forEach(item => { if (res.indexOf(item) === -1) { res.push(item) } }) return res}// testconst arr = [1, 1, 2, 3, 3]console.log(resetArr(arr)) // [1, 2, 3]

9、获取url参数

URLSearchParams 方法

// Create an instance of URLSearchParamsconst urlSearchParams = new URLSearchParams(window.location.search);// Convert the list of key-value pairs into an objectconst params = Object.fromEntries(urlSearchParams.entries());

split 方法


function getParams(url) { const res = {} if (url.includes(‘?’)) { const str = url.split(‘?’)[1] const arr = str.split(‘&’) arr.forEach(item => { const key = item.split(‘=’)[0] const val = item.split(‘=’)[1] res[key] = decodeURIComponent(val) // decode }) } return res}// testconst user = getParams(‘http://www.baidu.com?user=%E9%98%BF%E9%A3%9E&age=16')console.log(user) // {user:’abor’, age: ‘16’}

10、 事件总线 | 发布和订阅模式

class EventEmitter { constructor() { this.cache = {} }on(name, fn) { if (this.cache[name]) { this.cache[name].push(fn) } else { this.cache[name] = [fn] } }off(name, fn) { const tasks = this.cache[name] if (tasks) { const index = tasks.findIndex((f) => f === fn || f.callback === fn) if (index >= 0) { tasks.splice(index, 1) } } }emit(name, once = false) { if (this.cache[name]) { // Create a copy, if you continue to register the same event in the callback function, it will cause an endless loop const tasks = this.cache[name].slice() for (let fn of tasks) { fn(); } if (once) { delete this.cache[name] } } }}// testconst eventBus = new EventEmitter()const task1 = () => {console.log(‘task1’);}const task2 = () => {console.log(‘task2’);}eventBus.on(‘task’, task1)eventBus.on(‘task’, task2)eventBus.off(‘task’, task1)setTimeout(() => { eventBus.emit(‘task’) // task2}, 1000)
总结
以上就是我今天与您分享10个常用的JavaScript函数的全部内容。希望对您有所帮助,如果您有任何问题,请在留言区给我留言,我会尽快回复。
如果您觉得,我今天的内容对您有帮助,请记得给我点赞,并分享给您身边做开发的朋友,也许可以帮助到他。
最后,感谢您的阅读。


学习更多技能

请点击下方公众号

浏览 10
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报