万丈高楼平地起,地基打的牢,才能永远立于不败之地。今天给大家带来的是10个常见的 JavaScript 手写功能,重要的地方已添加注释。有的是借鉴别人的,有的是自己写的,如有不正确的地方,欢迎多多指正。

1、防抖

function debounce(fn, delay) {let timerreturn function (...args) {if (timer) {clearTimeout(timer)}timer = setTimeout(() => {fn.apply(this, args)}, delay)}
}// 测试
const task = () => {console.log('run task')
}
const debounceTask = debounce(task, 1000)
window.addEventListener('scroll', debounceTask)
复制代码

2、节流

function throttle(fn, delay) {let last = 0 // 上次触发时间return (...args) => {const now = Date.now()if (now - last > delay) {last = nowfn.apply(this, args)}}
}// 测试
const 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 objif (cache.get(obj)) return cache.get(obj) // 防止循环引用,程序进入死循环if (obj instanceof Date) return new Date(obj)if (obj instanceof RegExp) return new RegExp(obj)// 找到所属原型上的constructor,所属原型上的constructor指向当前对象的构造函数let cloneObj = new obj.constructor()cache.set(obj, cloneObj) // 缓存拷贝的对象,用于处理循环引用的情况for (let key in obj) {if (obj.hasOwnProperty(key)) {cloneObj[key] = deepClone(obj[key], cache) // 递归拷贝}}return cloneObj
}// 测试
const obj = { name: 'Jack', address: { x: 100, y: 200 } }
obj.a = obj // 循环引用
const newObj = deepClone(obj)
console.log(newObj.address === obj.address) // false
复制代码

4、实现 Promise

class MyPromise {constructor(executor) { // executor执行器this.status = 'pending' // 等待状态this.value = null // 成功或失败的参数this.fulfilledCallbacks = [] // 成功的函数队列this.rejectedCallbacks = [] // 失败的函数队列const that = thisfunction resolve(value) { // 成功的方法if (that.status === 'pending') {that.status = 'resolved'that.value = valuethat.fulfilledCallbacks.forEach(myFn => myFn(that.value)) //执行回调方法}}function reject(value) { //失败的方法if (that.status === 'pending') {that.status = 'rejected'that.value = valuethat.rejectedCallbacks.forEach(myFn => myFn(that.value)) //执行回调方法}}try {executor(resolve, reject)} catch (err) {reject(err)}}then(onFulfilled, onRejected) {if (this.status === 'pending') {// 等待状态,添加回调函数到成功的函数队列this.fulfilledCallbacks.push(() => {onFulfilled(this.value)})// 等待状态,添加回调函数到失败的函数队列this.rejectedCallbacks.push(() => {onRejected(this.value)})}if (this.status === 'resolved') { // 支持同步调用console.log('this', this)onFulfilled(this.value)}if (this.status === 'rejected') { // 支持同步调用onRejected(this.value)}}
}// 测试
function 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 = 5) {return new Promise((resolve, reject) => {const len = urls.lengthlet count = 0 // 当前进行到第几个任务const start = async () => {const url = urls.shift() // 从数组中拿取第一个任务if (url) {try {await axios.post(url)if (count == len - 1) {// 最后一个任务resolve()} else {count++// 成功,启动下一个任务start()}} catch (e) {count++// 失败,也启动下一个任务start()}}}// 启动limit个任务while (limit > 0) {start()limit -= 1}})
}// 测试
limitRequest(['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 = new Parent() // 原型链继承
Child.prototype.contructor = Child
Child.prototype.study = function () {console.log(this.name + ' is studying')
}// 测试
let child = new Child('xiaoming', 16)
console.log(child.name) // xiaoming
child.eat() // xiaoming is eating
child.study() // xiaoming is studying
复制代码

7、数组排序

sort 排序

// 对数字进行排序,简写
const arr = [3, 2, 4, 1, 5]
arr.sort((a, b) => a - b)
console.log(arr) // [1, 2, 3, 4, 5]// 对字母进行排序
const arr = ['b', 'c', 'a', 'e', 'd']
arr.sort((a, b) => {if (a > b) return 1else if (a < b) return -1else return 0
})
console.log(arr) // ['a', 'b', 'c', 'd', 'e']
复制代码

冒泡排序

function bubbleSort(arr) {let len = arr.lengthfor (let i = 0; i < len - 1; i++) {// 从第一个元素开始,比较相邻的两个元素,前者大就交换位置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}}// 每次遍历结束,都能找到一个最大值,放在数组最后}return arr
}//测试
console.log(bubbleSort([2, 3, 1, 5, 4])) // [1, 2, 3, 4, 5]
复制代码

8、数组去重

Set 去重

cosnt newArr = [...new Set(arr)]
复制代码

Array.from 去重

const newArr = Array.from(new Set(arr))
复制代码

indexOf 去重

function resetArr(arr) {let res = []arr.forEach(item => {if (res.indexOf(item) === -1) {res.push(item)}})return res
}// 测试
const arr = [1, 1, 2, 3, 3]
console.log(resetArr(arr)) // [1, 2, 3]
复制代码

9、获取url参数

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) // 解码})}return res
}// 测试
const user = getParams('http://www.baidu.com?user=%E9%98%BF%E9%A3%9E&age=16')
console.log(user) // { user: '阿飞', 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]) {// 创建副本,如果回调函数内继续注册相同事件,会造成死循环const tasks = this.cache[name].slice()for (let fn of tasks) {fn();}if (once) {delete this.cache[name]}}}
}// 测试
const 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)
复制代码

以上就是工作或求职中最常见的手写功能,你是不是全都掌握了呢,欢迎在评论区交流。如果文章对你有所帮助,不要忘了点上宝贵的一赞!

作者:前端阿飞
链接:https://juejin.cn/post/7031322059414175774
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

10个常见的前端手写功能,你全都会吗?相关推荐

  1. 10个常见的前端手写功能

    10个常见的前端手写功能 1.防抖 2.节流 3.深拷贝 JSON方法 递归拷贝 4.手写Promise 5.异步控制并发数 6.继承 ES5 继承(寄生组合继承) ES6继承 7.数组排序 sort ...

  2. 前端手写电子签名板实现方案

    前端手写电子签名板实现 作者:@ 很菜的小白在分享 时间:2022年12月29日 介绍 什么是电子签名 电子签名是指数据电文中以电子形式所含.所附用于识别签名人身份并表明签名人认可其中内容的数据.-- ...

  3. JavaScript进阶必会的手写功能

    JavaScript进阶的必要性 无论是学习react还是vue,它们都是js的应用框架.剥去他们的壳子看到的始终是js,所以作为一个前端大厨必须要熟练掌握好js这个大勺,才能烧出一顿好菜 无论是自我 ...

  4. JavaScript进阶必会的手写功能(二)

    JavaScript进阶必会的手写功能(一) 6. 手写浅拷贝 6.1 JavaScript数据类型分类 1. 简单数据类型: Number. String.Boolean.null.undefine ...

  5. 联想笔记本那些有手写功能_联想发YOGABOOK笔记本 全触控键盘能手写很炫

    腾讯数码讯(周硕)9月21日,联想正式在国内发布了此前在IFA首次亮相的全新Yoga系列二合一笔记本新品.这一代Yoga 5 Pro笔记本最大的特点是采用了4K分辨率超窄边框设计,看起来极简美观.而Y ...

  6. DroidPilot V2.1 手写功能特别版

    庆祝为国内某知名安卓设备厂商定制的DroidPilot V2.1 手写功能版发布,我们特别制作了这集视频,欢迎观看:http://v.youku.com/v_show/id_XNDk4Mzg2NTAw ...

  7. DL之DNN:利用DNN【784→50→100→10】算法对MNIST手写数字图片识别数据集进行预测、模型优化

    DL之DNN:利用DNN[784→50→100→10]算法对MNIST手写数字图片识别数据集进行预测.模型优化 导读 目的是建立三层神经网络,进一步理解DNN内部的运作机制 目录 输出结果 设计思路 ...

  8. wpf 切换搜狗输入法英文_搜狗输入法全新升级手写功能,中英数字自由写,告别切换丨本周新闻...

    搜狗AI合成主播雅妮 为您带来搜狗本周新闻播报 新 闻 原 文 .01. 2019搜狗全年营收超80亿人民币,创历史新高 近期,搜狗公布了2019年第四季度及全年未经审计的财务报告.财报显示,2019 ...

  9. 有道云笔记android手写,有道云笔记iPad版升级 新增手写功能

    近日,有道云笔记iPad版发布重大更新,新版增加的手写功能使得用户的笔记记录速度再次大幅提升.伴随此次更新,有道云笔记iPad版编辑器也进行了全面升级.新版编辑器基于iOS5系统特性进行了重新开发,可 ...

最新文章

  1. CBS电信项目中的三户一品总结
  2. qtcreator安装后的设置
  3. java交易系统_基于SSM框架的JAVA二手交易系统
  4. [Swift]LeetCode75. 颜色分类 | Sort Colors
  5. flyway常用配置_Spring Boot 2 实战:使用 Flyway 管理你数据库的版本变更
  6. 让Tee 7.x版本和FastReport 3.x版本共存
  7. SAP CRM Business transaction save mode
  8. ASP.NET MVC3 中的AJAX
  9. 2021-11-10 动态粒子背景插件
  10. 【操作系统/OS笔记05】非连续内存分配:分段、分页、页表
  11. Python面试题解析之网络编程与并发
  12. Hadoop生态圈-Flume的组件之自定义Sink
  13. 提取Flash芯片信息
  14. 车辆模型-动力学模型(Dynamics Model)
  15. 四、回归分析之线性回归模型构建
  16. 企业微信之发送应用消息案例
  17. JDK+JAVA+TOMCAT+MAVEN+IDEA的安装配置以及新建项目
  18. idea运行javaweb项目出现“该网页无法正常运作”
  19. 毁掉一个孩子的几个方法 有多少家长正在这么做?
  20. 1年19款,款款口碑爆棚,Cocos 插件大佬的真面目竟是?

热门文章

  1. 干货分享 | 速速围观,想要BIM落地,这些应用阶段都不可或缺
  2. 人间地狱服务器一直显示有人,人间地狱常见问题及解决方法_Hell Let Loose常见问题QA_游戏堡...
  3. 2022年5月4号SSM框架整合学习四:
  4. ubuntu安装todesk远程控制简明教程
  5. 安卓开发之基本UI设计
  6. 2023版Python数据分析,学习路径拆解及资源推荐(附详细思维导图)
  7. Libra (介绍) 建立一个简单的全球货币和金融基础 (1)
  8. msa.h:没有那个文件或目录
  9. ChatGPT可以出图片了!独家技巧披露:巧用ChatGPT 批量生成图文并茂的画报
  10. 40万封机密邮件泄露,高管辞职