10个常见的JavaScript函数的前端手写功能,你都知道吗?

英文 | https://medium.com/@cookbug/10-common-front-end-handwriting-functions-do-you-know-all-of-them-9deb1ffb922d
翻译 | 杨小爱
function debounce(fn, delay) {let timerreturn 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 timereturn (…args) => {const now = Date.now()if (now-last> delay) {last = nowfn.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 objif (obj === null) return objif (cache.get(obj)) return cache.get(obj) // Prevent circular references, the program enters an infinite loopif (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 objectlet cloneObj = new obj.constructor()cache.set(obj, cloneObj) // Cache copied objects, used to handle circular referencesfor (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 executorthis.status =’pending’ // waiting statusthis.value = null // parameter of success or failurethis.fulfilledCallbacks = [] // Successful function queuethis.rejectedCallbacks = [] // Failed function queueconst that = thisfunction resolve(value) {// successful methodif (that.status ===’pending’) {that.status =’resolved’that.value = valuethat.fulfilledCallbacks.forEach(myFn => myFn(that.value)) //Execute callback method}}function reject(value) {//Failed methodif (that.status ===’pending’) {that.status =’rejected’that.value = valuethat.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 queuethis.fulfilledCallbacks.push(() => {onFulfilled(this.value)})// Waiting state, add the callback function to the failed function queuethis.rejectedCallbacks.push(() => {onRejected(this.value)})}if (this.status ===’resolved’) {// support synchronous callconsole.log(‘this’, this)onFulfilled(this.value)}if (this.status ===’rejected’) {// Support synchronous callonRejected(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})
function limitRequest(urls = [], limit = 3) {return new Promise((resolve, reject) => {const len = urls.lengthlet count = 0// Start limit tasks simultaneouslywhile (limit> 0) {start()limit -= 1}function start() {const url = urls.shift() // Take the first task from the arrayif (url) {axios.post(url).finally(() => {if (count == len-1) {// The last task is completedresolve()} else {// After completion, start the next taskcount++start()}})}}})}// testlimitRequest([‘http://xxa','http://xxb','http://xxc','http://xxd','http://xxe'])
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.lengthfor (let i = 0; i <len-1; i++) {// Starting from the first element, compare two adjacent elements, exchange positions if the former is biggerfor (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 loopconst 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)
学习更多技能
请点击下方公众号
![]()

评论
