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、节流
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)
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)
复制代码
4、实现 Promise
class MyPromise {
constructor(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)
},
err => {
console.log('err', err)
})
复制代码
5、异步控制并发数
function limitRequest(urls = [], limit = 3) {
return new Promise((resolve, reject) => {
const len = urls.length
let count = 0
while (limit > 0) {
start()
limit -= 1
}
function start() {
const url = urls.shift()
if (url) {
axios.post(url).finally(() => {
if (count == len - 1) {
resolve()
} else {
count++
start()
}
})
}
}
})
}
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)
child.eat()
child.study()
复制代码
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
// 从第一个元素开始,比较相邻的两个元素,前者大就交换位置
for (let j = 0
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))
复制代码
9、获取 url 参数
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)
复制代码
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')
}, 1000)
复制代码
11、HTML便签解码
htmlFormat(html) {
if (!html) {
return false
}
var temp = ""
if(html.length == 0) return ""
temp = html.replace(/&
temp = temp.replace(/<
temp = temp.replace(/>
temp = temp.replace(/ 
temp = temp.replace(/&
temp = temp.replace(/"
return temp
}
//测试
let p = '<p>hello</p>'
let q = htmlFormat(p)
console.log(q) //<p>hello</p>
12、小程序判断滑动方向及滑动距离
touchStart = (e) => {
let sx = e.touches[0].pageX
let sy = e.touches[0].pageY
const touchStart = [sx, sy]
this.setState({ touchStart })
}
touchMove = (e) => {
const { touchStart } = this.state
let sx = e.touches[0].pageX
let sy = e.touches[0].pageY
const touchMove = [sx, sy]
console.error(touchStart[1] - touchMove[1])
}
touchEnd = () => {
const { touchStart, touchMove } = this.state
console.error(touchStart)
console.error(touchMove)
if (touchMove[0] === 0) return
if (touchStart[0] - touchMove[0] > 0) {
console.log('向左滑,这里可以调用方法,及页面跳转事件')
} else if (touchStart[0] - touchMove[0] < 0) {
console.log('向右滑,这里可以调用方法,及页面跳转事件')
} else {
console.log('向上或向下滑动')
}
console.error(touchStart[0] - touchMove[0])
console.error(touchStart[1] - touchMove[1])
}