您现在的位置是:亿华云 > 数据库

十个常见的前端手写功能,你全都会吗?

亿华云2025-10-02 08:54:32【数据库】0人已围观

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

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

1、个常功防抖

function debounce(fn,前端全都 delay) {    let timer   return function (...args) {      if (timer) {        clearTimeout(timer)     }     timer = setTimeout(() => {        fn.apply(this, args)     }, delay)   } } // 测试 function task() {    console.log(run task) } const debounceTask = debounce(task, 1000) window.addEventListener(scroll, debounceTask) 

2、云南idc服务商节流

function throttle(fn,手写 delay) {    let last = 0 // 上次触发时间   return (...args) => {      const now = Date.now()     if (now - last > delay) {        last = now       fn.apply(this, args)     }   } } // 测试 function 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) // 防止循环引用,前端全都程序进入死循环   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 = this     function resolve(value) {  // 成功的方法       if (that.status === pending) {          that.status = resolved         that.value = value         that.fulfilledCallbacks.forEach(myFn => myFn(that.value)) //执行回调方法       }     }     function reject(value) {  //失败的方法       if (that.status === pending) {          that.status = rejected         that.value = value         that.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 = 3) {    return new Promise((resolve, reject) => {      const len = urls.length     let 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) {            if (count == len - 1) {              // 最后一个任务失败             resolve()           } else {              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 = Object.create(Parent.prototype) 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() console.log(arr) // [a, b, c, d, e]  

冒泡排序

function bubbleSort(arr) {    let len = arr.length   for (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 参数

URLSearchParams 方法

// 创建一个URLSearchParams实例 const urlSearchParams = new URLSearchParams(window.location.search); // 把键值对列表转换为一个对象 const 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) // 解码     })   }   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) 

以上就是工作或求职中最常见的手写功能,你是不是全都掌握了呢

很赞哦!(431)