激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - 編程技術(shù) - 十個(gè)常見的前端手寫功能,你全都會嗎?

十個(gè)常見的前端手寫功能,你全都會嗎?

2021-12-19 23:13CRMEB 編程技術(shù)

萬丈高樓平地起,地基打的牢,才能永遠(yuǎn)立于不敗之地。今天給大家?guī)淼氖?0個(gè)常見的 JavaScript 手寫功能,重要的地方已添加注釋。有的是借鑒別人的,有的是自己寫的,如有不正確的地方,歡迎多多指正。

萬丈高樓平地起,地基打的牢,才能永遠(yuǎn)立于不敗之地。今天給大家?guī)淼氖?0個(gè)常見的 JavaScript 手寫功能,重要的地方已添加注釋。有的是借鑒別人的,有的是自己寫的,如有不正確的地方,歡迎多多指正。

十個(gè)常見的前端手寫功能,你全都會嗎?

1、防抖

  1. function debounce(fn, delay) {
  2. let timer
  3. return function (...args) {
  4. if (timer) {
  5. clearTimeout(timer)
  6. }
  7. timer = setTimeout(() => {
  8. fn.apply(this, args)
  9. }, delay)
  10. }
  11. }
  12. // 測試
  13. function task() {
  14. console.log('run task')
  15. }
  16. const debounceTask = debounce(task, 1000)
  17. window.addEventListener('scroll', debounceTask)

2、節(jié)流

  1. function throttle(fn, delay) {
  2. let last = 0 // 上次觸發(fā)時(shí)間
  3. return (...args) => {
  4. const now = Date.now()
  5. if (now - last > delay) {
  6. last = now
  7. fn.apply(this, args)
  8. }
  9. }
  10. }
  11. // 測試
  12. function task() {
  13. console.log('run task')
  14. }
  15. const throttleTask = throttle(task, 1000)
  16. window.addEventListener('scroll', throttleTask)

3、深拷貝

  1. function deepClone(obj, cache = new WeakMap()) {
  2. if (typeof obj !== 'object') return obj // 普通類型,直接返回
  3. if (obj === null) return obj
  4. if (cache.get(obj)) return cache.get(obj) // 防止循環(huán)引用,程序進(jìn)入死循環(huán)
  5. if (obj instanceof Date) return new Date(obj)
  6. if (obj instanceof RegExp) return new RegExp(obj)
  7. // 找到所屬原型上的constructor,所屬原型上的constructor指向當(dāng)前對象的構(gòu)造函數(shù)
  8. let cloneObj = new obj.constructor()
  9. cache.set(obj, cloneObj) // 緩存拷貝的對象,用于處理循環(huán)引用的情況
  10. for (let key in obj) {
  11. if (obj.hasOwnProperty(key)) {
  12. cloneObj[key] = deepClone(obj[key], cache) // 遞歸拷貝
  13. }
  14. }
  15. return cloneObj
  16. }
  17. // 測試
  18. const obj = { name: 'Jack', address: { x: 100, y: 200 } }
  19. obj.a = obj // 循環(huán)引用
  20. const newObj = deepClone(obj)
  21. console.log(newObj.address === obj.address) // false

4、實(shí)現(xiàn) Promise

  1. class MyPromise {
  2. constructor(executor) { // executor執(zhí)行器
  3. this.status = 'pending' // 等待狀態(tài)
  4. this.value = null // 成功或失敗的參數(shù)
  5. this.fulfilledCallbacks = [] // 成功的函數(shù)隊(duì)列
  6. this.rejectedCallbacks = [] // 失敗的函數(shù)隊(duì)列
  7. const that = this
  8. function resolve(value) { // 成功的方法
  9. if (that.status === 'pending') {
  10. that.status = 'resolved'
  11. that.value = value
  12. that.fulfilledCallbacks.forEach(myFn => myFn(that.value)) //執(zhí)行回調(diào)方法
  13. }
  14. }
  15. function reject(value) { //失敗的方法
  16. if (that.status === 'pending') {
  17. that.status = 'rejected'
  18. that.value = value
  19. that.rejectedCallbacks.forEach(myFn => myFn(that.value)) //執(zhí)行回調(diào)方法
  20. }
  21. }
  22. try {
  23. executor(resolve, reject)
  24. } catch (err) {
  25. reject(err)
  26. }
  27. }
  28. then(onFulfilled, onRejected) {
  29. if (this.status === 'pending') {
  30. // 等待狀態(tài),添加回調(diào)函數(shù)到成功的函數(shù)隊(duì)列
  31. this.fulfilledCallbacks.push(() => {
  32. onFulfilled(this.value)
  33. })
  34. // 等待狀態(tài),添加回調(diào)函數(shù)到失敗的函數(shù)隊(duì)列
  35. this.rejectedCallbacks.push(() => {
  36. onRejected(this.value)
  37. })
  38. }
  39. if (this.status === 'resolved') { // 支持同步調(diào)用
  40. console.log('this', this)
  41. onFulfilled(this.value)
  42. }
  43. if (this.status === 'rejected') { // 支持同步調(diào)用
  44. onRejected(this.value)
  45. }
  46. }
  47. }
  48. // 測試
  49. function fn() {
  50. return new MyPromise((resolve, reject) => {
  51. setTimeout(() => {
  52. if(Math.random() > 0.6) {
  53. resolve(1)
  54. } else {
  55. reject(2)
  56. }
  57. }, 1000)
  58. })
  59. }
  60. fn().then(
  61. res => {
  62. console.log('res', res) // res 1
  63. },
  64. err => {
  65. console.log('err', err) // err 2
  66. })

5、異步控制并發(fā)數(shù)

  1. function limitRequest(urls = [], limit = 3) {
  2. return new Promise((resolve, reject) => {
  3. const len = urls.length
  4. let count = 0 // 當(dāng)前進(jìn)行到第幾個(gè)任務(wù)
  5. const start = async () => {
  6. const url = urls.shift() // 從數(shù)組中拿取第一個(gè)任務(wù)
  7. if (url) {
  8. try {
  9. await axios.post(url)
  10. if (count == len - 1) {
  11. // 最后一個(gè)任務(wù)成功
  12. resolve()
  13. } else {
  14. count++
  15. // 成功,啟動下一個(gè)任務(wù)
  16. start()
  17. }
  18. } catch (e) {
  19. if (count == len - 1) {
  20. // 最后一個(gè)任務(wù)失敗
  21. resolve()
  22. } else {
  23. count++
  24. // 失敗,啟動下一個(gè)任務(wù)
  25. start()
  26. }
  27. }
  28. }
  29. }
  30. // 啟動limit個(gè)任務(wù)
  31. while (limit > 0) {
  32. start()
  33. limit -= 1
  34. }
  35. })
  36. }
  37. // 測試
  38. limitRequest(['http://xxa', 'http://xxb', 'http://xxc', 'http://xxd', 'http://xxe'])

6、ES5繼承(寄生組合繼承)

  1. function Parent(name) {
  2. this.name = name
  3. }
  4. Parent.prototype.eat = function () {
  5. console.log(this.name + ' is eating')
  6. }
  7. function Child(name, age) {
  8. Parent.call(this, name)
  9. this.age = age
  10. }
  11. Child.prototype = Object.create(Parent.prototype)
  12. Child.prototype.contructor = Child
  13. Child.prototype.study = function () {
  14. console.log(this.name + ' is studying')
  15. }
  16. // 測試
  17. let child = new Child('xiaoming', 16)
  18. console.log(child.name) // xiaoming
  19. child.eat() // xiaoming is eating
  20. child.study() // xiaoming is studying

7、數(shù)組排序

sort 排序

  1. // 對數(shù)字進(jìn)行排序,簡寫
  2. const arr = [3, 2, 4, 1, 5]
  3. arr.sort((a, b) => a - b)
  4. console.log(arr) // [1, 2, 3, 4, 5]
  5. // 對字母進(jìn)行排序,簡寫
  6. const arr = ['b', 'c', 'a', 'e', 'd']
  7. arr.sort()
  8. console.log(arr) // ['a', 'b', 'c', 'd', 'e']

冒泡排序

  1. function bubbleSort(arr) {
  2. let len = arr.length
  3. for (let i = 0; i < len - 1; i++) {
  4. // 從第一個(gè)元素開始,比較相鄰的兩個(gè)元素,前者大就交換位置
  5. for (let j = 0; j < len - 1 - i; j++) {
  6. if (arr[j] > arr[j + 1]) {
  7. let num = arr[j]
  8. arr[j] = arr[j + 1]
  9. arr[j + 1] = num
  10. }
  11. }
  12. // 每次遍歷結(jié)束,都能找到一個(gè)最大值,放在數(shù)組最后
  13. }
  14. return arr
  15. }
  16. //測試
  17. console.log(bubbleSort([2, 3, 1, 5, 4])) // [1, 2, 3, 4, 5]

8、數(shù)組去重

Set 去重

  1. cosnt newArr = [...new Set(arr)]

Array.from 去重

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

indexOf 去重

  1. function resetArr(arr) {
  2. let res = []
  3. arr.forEach(item => {
  4. if (res.indexOf(item) === -1) {
  5. res.push(item)
  6. }
  7. })
  8. return res
  9. }
  10. // 測試
  11. const arr = [1, 1, 2, 3, 3]
  12. console.log(resetArr(arr)) // [1, 2, 3]

9、獲取 url 參數(shù)

URLSearchParams 方法

  1. // 創(chuàng)建一個(gè)URLSearchParams實(shí)例
  2. const urlSearchParams = new URLSearchParams(window.location.search);
  3. // 把鍵值對列表轉(zhuǎn)換為一個(gè)對象
  4. const params = Object.fromEntries(urlSearchParams.entries());

split 方法

  1. function getParams(url) {
  2. const res = {}
  3. if (url.includes('?')) {
  4. const str = url.split('?')[1]
  5. const arr = str.split('&')
  6. arr.forEach(item => {
  7. const key = item.split('=')[0]
  8. const val = item.split('=')[1]
  9. res[key] = decodeURIComponent(val) // 解碼
  10. })
  11. }
  12. return res
  13. }
  14. // 測試
  15. const user = getParams('http://www.baidu.com?user=%E9%98%BF%E9%A3%9E&age=16')
  16. console.log(user) // { user: '阿飛', age: '16' }

10、事件總線 | 發(fā)布訂閱模式

  1. class EventEmitter {
  2. constructor() {
  3. this.cache = {}
  4. }
  5. on(name, fn) {
  6. if (this.cache[name]) {
  7. this.cache[name].push(fn)
  8. } else {
  9. this.cache[name] = [fn]
  10. }
  11. }
  12. off(name, fn) {
  13. const tasks = this.cache[name]
  14. if (tasks) {
  15. const index = tasks.findIndex((f) => f === fn || f.callback === fn)
  16. if (index >= 0) {
  17. tasks.splice(index, 1)
  18. }
  19. }
  20. }
  21. emit(name, once = false) {
  22. if (this.cache[name]) {
  23. // 創(chuàng)建副本,如果回調(diào)函數(shù)內(nèi)繼續(xù)注冊相同事件,會造成死循環(huán)
  24. const tasks = this.cache[name].slice()
  25. for (let fn of tasks) {
  26. fn();
  27. }
  28. if (once) {
  29. delete this.cache[name]
  30. }
  31. }
  32. }
  33. }
  34. // 測試
  35. const eventBus = new EventEmitter()
  36. const task1 = () => { console.log('task1'); }
  37. const task2 = () => { console.log('task2'); }
  38. eventBus.on('task', task1)
  39. eventBus.on('task', task2)
  40. eventBus.off('task', task1)
  41. setTimeout(() => {
  42. eventBus.emit('task') // task2
  43. }, 1000)

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

原文鏈接:https://www.toutiao.com/a7042179770611696158/

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产亚洲黑人性受xxxx精品 | 国产精品自在线拍 | 久久精品污 | av电影观看 | 成年免费大片黄在线观看岛国 | 免费久久精品 | 国产一区网址 | 美女喷水网站 | 在线播放亚洲视频 | av影院在线播放 | av成人免费在线观看 | 综合网天天射 | 黄色网址免费进入 | 免费午夜视频在线观看 | 欧美成人午夜影院 | 性少妇videosexfreexx | 毛片免费一区二区三区 | 在线播放免费视频 | 免费黄网站在线播放 | 97精品国产高清在线看入口 | 一级做a爰性色毛片免费 | 色妇视频 | 一区视频 | 欧美日本不卡 | 视频一区二区视频 | 人人看人人艹 | 亚洲五码在线观看视频 | 亚洲国产精久久久久久久 | www.xxx视频| 一级毛片在线免费观看 | 精品久久久久久久久久久久久久久久久久久 | 午夜小电影 | 久久久久久久久久久久免费 | www.国产一区.com| 国产18成人免费视频 | 国产91对白叫床清晰播放 | 深夜影院一级毛片 | 久久精品国产99久久6动漫亮点 | 免费观看国产精品视频 | 亚洲精品久久久久久下一站 | 精品亚洲一区二区三区 |