手写系列
防抖 节流
防抖 debounce
每次事件触发后总是等待一段时间执行,如果在等待时间内事件再次触发,则重新计算等待时间(停止触发的时候只会执行一次,最后一次生效)
javaScript
function debounce(fun, wait) {
let timer = null
return (...args) => {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fun.apply(this, args)
}, wait)
}
}TS 版本
typescript
function debounce(func: Function, delay: number, immediate = false): Function {
let timer: number | undefined
return function(this: unknown, ...args: any[]) {
if (immediate) {
func.apply(this, args) // 确保引用函数的指向正确,并且函数的参数也不变
immediate = false
return
}
clearTimeout(timer)
timer = setTimeout(() => {
func.apply(this, args)
}, delay)
}
}首次立即执行 防抖
javaScript
/**
* 可配置防抖函数
* @param {function} func 回调函数
* @param {number} wait 表示时间窗口的间隔
* @param {boolean} immediate 设置为ture时,是否立即调用函数
* @return {function} 返回客户调用函数
*/
function debounceFirst(func, wait, immediate) {
let timeout;
return function executedFunction() {
const context = this;
const args = arguments;
const later = function() {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
clearTimeout(timeout);
if (immediate && !timeout) {
func.apply(context, args);
}
timeout = setTimeout(() => {
later();
}, wait);
};
}节流 throttle
连续触发事件但在n秒内只执行一次函数
javaScript
function throttle(fun, wait) {
let timer = null
return (...args) => {
if (!timer) {
timer = setTimeout(() => {
fun.apply(this, args)
timer = null
}, wait)
}
}
}
function throttle(fun, wait) {
let pre = 0
return (...args) => {
const now = Date.now()
if (pre - now > wait){
fun.apply(this, args)
pre = now
}
}
}注: fun.apply(this, args)都可使用fun.call(this, ...args)替换
手写一个 new
javascript
function _new(fn, ...args) {
let obj = {}
obj.__proto__ = fn.prototype
fn.apply(obj, args)
return obj
}手写一个 forEach
javascript
Array.prototype._forEach = function (callback) {
for (let i = 0; i < this.length; i++) {
callback(this[i], i, this)
}
}手写一个 map
javascript
Array.prototype._map = function (callback) {
const res = []
for (let i = 0; i < this.length; i++) {
res.push(callback(this[i], i, this))
}
return res
}手写一个 filter
javascript
Array.prototype._filter = function (callback) {
let res = []
for (let i = 0; i < this.length; i++) {
callback(this[i], i, this) && res.push(this[i])
}
return res
}手写一个 every
javascript
Array.prototype._every = function (callback) {
let flag = true
for (let i = 0; i < this.length; i++) {
flag = callback(this[i], i, this)
if (!flag) break
}
return flag
}手写一个 some
javascript
Array.prototype._some = function (callback) {
let flag = false
for (let i = 0; i < this.length; i++) {
flag = callback(this[i], i, this)
if (flag) break
}
return flag
}手写一个 reduce
javascript
Array.prototype._reduce = function (callback, ...args) {
let start = 0,
pre
if (args.length) {
pre = args[0]
} else {
pre = this[0]
start = 1
}
for (let i = start; i < this.length; i++) {
pre = callback(pre, this[i], i, this)
}
return pre
}手写一个 findIndex
javascript
Array.prototype._findIndex = function (callback) {
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
return i
}
}
return -1
}手写一个 find
javascript
Array.prototype._find = function (callback) {
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
return this[i]
}
}
return undefined
}手写一个 fill
javascript
Array.prototype._fill = function (value, start = 0, end) {
end = end || this.length
for (let i = start; i < end; i++) {
this[i] = value
}
return this
}compose 函数
compose 函数可以将需要嵌套执行的函数平铺,嵌套执行就是一个函数的返回值将作为另一个函数的参数。
js
// 参数从右往左执行
const res = compose(second, first)(10)compose 方法实现,需要借助一下 Array.prototype.reduceRight
js
const compose = function(){
// 将接收的参数存到一个数组, args == [multiply, add]
const args = [].slice.apply(arguments)
return function(x) {
return args.reduceRight((res, cb) => cb(res), x)
}
}使用 ES6 语法会更加简洁
js
const compose = (...args) => x => args.reduceRight((res, cb) => cb(res), x);pipe 函数
pipe 函数跟 compose 函数的左右是一样的,也是将参数平铺,只不过他的顺序是 从左往右,只需要将 reduceRight 替换为 reduce 即可。
js
const pipe = function(){
const args = [].slice.apply(arguments);
return function(x) {
return args.reduce((res, cb) => cb(res), x);
}
}ES6 写法
js
const pipe = (...args) => x => args.reduce((res, cb) => cb(res), x)