手写前端常用工具方法(一)
Promise的简单实现
function myPromise (executor) {
this.value = null
this.fail = null
this.status = 'pending'
this.onResolvedQueue = []
this.onRejectedQueue = []
var _this = this
function resolve (value) {
if (_this.status !== 'pending') {
return
}
_this.value = value
_this.status = 'resolved'
_this.onResolvedQueue.forEach(resolved => resolved(_this.value))
}
funciton reject (error) {
if (_this.status !== 'pending') {
return
}
_this.fail = error
_this.status = 'rejected'
_this.onRejectedQueue.forEach(rejected => rejected(_this.fail))
}
executor(resolve, reject)
}
myPromise.prototype.then = function (onResolved, onRejected) {
if (typeof onResolved !== 'function') {
onResolved = function (x) {resolve(x)}
}
if (typeof onRejected !== 'function') {
onRejected = function (e) {reject(e)}
}
var _this = this
if (_this.status === 'resolved') {
onResolved(_this.value)
} else if (_this.status === 'rejected') {
onRejected(_this.fail)
} else {
_this.onResolvedQueue.push(onResolved)
_this.onRejectedQueue.push(onReejcted)
}
return this
}
节流
function throttle (fn, delay) {
let last = 0
return function () {
let context = this
let now = +new Date()
if (now - last >= delay) {
last = now
fn.apply(context, arguments)
}
}
}
防抖
function debounce (fn, delay) {
let timer = null
return function () {
let context = this
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(context, arguments)
}, delay)
}
}
new
function myNew (fn) {
// 实例
const res = {}
if (fn.prototype !== null) {
res.__proto__ = fn.prototype
}
const args = Array.prototype.slice.call(arguments, 1)
const ret = fn.apply(res, args)
if ((typeof ret === 'object' || typeof ret === 'function') && ret !== null) {
return ret
}
return res
}
call
Function.prototype.myCall = function (context) {
context.fn = this
const args = [...arguments].slice(1)
const result = context.fn(...args)
delete context.fn
return result
}
apply
Funcition.prototype.myApply = function (context) {
context.fn = this
let result
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn
}
delete context.fn
return result
}
bind
Function.prototype.myBind = function (context) {
const fn = this
let args = Array.prototype.slice.call(arguments, 1)
if (typeof fn !== 'function) {
throw new TypeError('must be function')
}
return function () {
let fnArgs = args.concat(Array.prototype.slice.call(arguments))
return fn.apply(args, fnArgs)
}
}