call、apply、bind、promise、节流防抖、Set等手写
call
call作用
官方:把调用一个对象的一个方法,以另一个对象替换当前对象; 我的理解:调用函数的时候改变this指向。
Function.prototype.myCall = function () {
const ctx = arguments[0] || {}
ctx.fun = this
const argv = arguments.slice(1)
return ctx.fun(...argv)
}
apply
Function.prototype.myApply = function () {
const ctx = arguments[0]
ctx.fun = this
return ctx.fun(...arguments[1])
}
bind
改变this指向但不执行
Function.prototype.myBind = function() {
ctx = arguments[0] || window;
const argv = arguments.slice(1)
ctx.fun = this
return function() {
return ctx.fun(...argv)
}
}
Promise
prototype写法
const STATUS = {
pending: 'pending',
fulfilled: 'fulfilled',
rejected: 'rejected'
}
function myPromise(executor) {
executor(resolve.bind(this), reject.bind(this))
this.status = STATUS['pending']
function resolve(value) {
if(this.status === STATUS['pending']) {
this.value = value
this.onFulfilledCache && this.onFulfilledCache(value)
}
}
function reject(reason) {
if(this.status === STATUS['pending']) {
this.reason = reason
this.onRejectedCache && this.onRejectedCache(reason)
}
}
}
myPromise.prototype.then = function(onFulfilled, onRejected) {
if(this.status === STATUS['fulfilled']) {
onFulfilled(this.value)
} else if(this.status === STATUS['rejected']) {
onRejected(this.reason)
} else if(this.status === STATUS['pending']){
this.onFulfilledCache = onFulfilled
this.onRejectedCache = onRejected
}
}
class写法
class myPromise2 {
executor(resolve, reject)
status = STATUS['pending']
// resolve和reject为什么要用箭头函数?
// 如果直接调用的话,普通函数this指向的是window或者undefined
// 用箭头函数就可以让this指向当前实例对象
resolve = (value) => {
if (status === STATUS['pending']) {
this.value = value
this.onFulfilledCache && this.onFulfilledCache()
}
}
reject = (reason) => {
if (status === STATUS['pending']) {
this.reason = reason
this.onRejectedCache && this.onRejectedCache()
}
}
then(onFulfilled, onRejected) {
if (this.status === STATUS['fulfilled']) {
onFulfilled(this.value)
} else if (this.status === STATUS['rejected']) {
onRejected(this.value)
} else if(this.status === STATUS['pending']) {
this.onFulfilledCache = onFulfilled
this.onRejectedCache = onRejected
}
}
}
节流防抖
防抖:对一个需要执行的函数,等待一段时间再执行,如果这段时间内又触发了这个函数,则重新计时。
function debounce(fn, delay = 200) {
let timer;
return function () {
// 重新计时
timer && clearTimeout(timer);
timer = setTimeout(fn.bind(this), delay, ...arguments);
}
}
节流:对一个需要执行的函数,在一段时间内连续触发时,只执行一次
// 时间戳
function throttle(fn, delay = 200) {
let pre = Date.now()
return function () {
const now = Date.now()
if (now - pre > delay) {
fn.call(this, ...arguments)
pre = now
}
}
}
// 定时器
function throttle(fn, delay = 200) {
let timer
return function () {
if(!timer) {
setTimeout(() => {
fn.call(this, ...arguments)
clearTimeout(timer)
}, delay)
}
}
}
手写Set
loading。。。