1.手写防抖节流
function debounce(f, wait) {
let timer
return (...args) => {
clearTimeout(timer)
timer = setTimeout(() => {
f(...args)
}, wait)
}
}
function throttle(f, wait) {
let timer
let _this = this
return (...args) => {
if (timer) return
timer = setTimeout(() => {
f.call(_this,...args)
timer = null
//在n秒后执行完毕关闭定时器,在n秒内未执行函数
//定时器一直存在,导致函数在n秒内只能执行一次
}, wait)
}
}
2.手写bind
if (!Function.prototype.bind) {
Function.prototype.bind = function (o/*,args*/) {
let self = this
let boundArgs = arguments //将bind对应的参数保存
return () => { //函数可以接受到参数
let args = [] //储存需要bind的参数
let i
for (i = 1; i < boundArgs.length; i++) {
args.push(boundArgs[i])
}
for (i = 0; i < arguments.length; i++) {
args.push(arguments[i])
}
return self.apply(o, args)
}
}
}
bind函数多次调用会以第一次调用的this为准,而softbind会以最后一次为准
3.闭包案例
//闭包 --- 一个函数返回另一个函数
function bibao() {
let a = 1
return () => {
return a
}
}
//意义: 延长变量生命周期 ; 创造私有环境
//闭包: 变量会常驻内存 不会被垃圾回收
4.手写compose函数,从右向左结合函数
const compose = (...func) => {
return func.reduce(
//先转置,从右往左结合函数
(f, g) =>
(...args) =>
f(g(...args))
)
}
const sum = x => x + 5
const multi = x => x * 10
const add = x => x + 10
console.log(compose(sum, multi, add)(10))
5.实现loadsh.get 获取对应路径的值
//实现loadsh.get() _.get(object,path,defaultValue) 获取对应路径的值
//a[0][1][2] => a.0.1.2 => [a,0,1,2]
const get = (o, path = '', defaultValue) => {
if (typeof path !== 'string' && !Array.isArray(path)) {
throw new Error(`${path} is not string or array`)
}
if (!Array.isArray(path)) {
//如果不是数组,只能是字符串
const paths = path
.replace(/\[(\w+)\]/g, '.$1')
.replace(/\['(\w+)'\]/g, '$1')
.replace(/\["(\w+)"\]/g, '$1')
.split('.')
}
const paths = path
let res = o
for (const p of paths) {
res = res?.[p];//存在则读取属性
}
return res == undefined ? defaultValue : res
}
const test = { a: { b: { c: 100 } } }
console.log(get(test, 'a.b.c', 100), get(test, 'a.c', 200), get(test, ['a', 'b', 'c'], 200));
6.在微任务之中添加微任务,该任务会优先于其他任务,所以递归调用微任务应谨慎处理
7.对象扁平化
function flatter(obj) {
let ans = {}
if (Object.prototype.toString.call(obj) !== '[object Object]') {
return obj
}
function helper(key, value) {
if (typeof value !== 'object') {
if (key) ans[key] = value
} else if (Array.isArray(value)) {
if (value.length == 0) {
ans[key] = []
}
for (let i in value) {
//跟之前的key结合,形成新的key值
helper(`${key}[${i}]`, value[i])
}
} else if (Object.prototype.toString.call(obj) == '[object Object]') {
let keys = Object.keys(value)
if (keys.length == 0 && key) {
ans[key] = {}
}
keys.forEach(item => {
helper(key ? `${key}.${item}` : `${item}`, value[item])
})
}
}
helper('', obj)
return ans
}
8.实现promise.all
//实现promise.all
const p1 = Promise.resolve('p1')
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p2 延时一秒')
}, 1000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p3 延时两秒')
}, 2000)
})
function promiseAll(promiseArr) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promiseArr)) throw new Error('syntax error') //错误处理
let ans = []
let count = 0
for (let i = 0; i < promiseArr.length; i++) {
Promise.resolve(promiseArr[i]).then(res => {
count++
ans[i] = res
if (count == promiseArr.length) {
resolve(ans)
}
}).catch(err => {
reject(err)
})
}
})
}
9.实现promise.race 中一个就返回
function promiseRace(promiseArr) {
if (!Array.isArray(promiseArr)) throw new TypeError('syntax error')
if (promiseArr.length === 0) return
return new Promise((resolve, reject) => {
for (let i = 0; i < promiseArr.length; i++) {
Promise.resolve(promiseArr[i])
.then(res => {
resolve(res)
})
.catch(err => {
reject(err)
})
}
})
}
10.Promise.any 所有失败返回失败,一个成功返回成功 ,忽略所有拒绝值,直到第一个成功
function promiseAny(promiseArr) {
if (!Array.isArray(promiseArr) || promiseArr.length == 0) {
return Promise.reject('TypeError')
}
return new Promise((resolve, reject) => {
let count = 0, ans = []
for (let i = 0; i < promiseArr.length; i++) {
Promise.resolve(promiseArr[i])
.then(value => {
resolve(value)
})
.catch(err => {
count++
ans[i] = err
if (count == promiseArr.length) {
reject(ans)
}
})
}
})
}
11.ES5实现类以及继承
function Animal(age){
this.age = age
this.eat = function(){
}
}
function Cat(){
Animal.call(this)
}
Cat.prototype = Object.create(Animal.prototype)
Cat.prototype.constructor = Cat