手写一个call方法
Function.prototype.myCall = function (context,...args) {
if (typeof this!== 'function') {
console.error('type error')
}
let context = context || window
context.fn = this
let result = context.fn(...args)
delete context.fn
return result
}
手写一个apply方法
Function.prototype.myApply = function (context,args) {
if (typeof this!== 'function') {
console.error('type error')
}
let context = context || window
context.fn = this
let result
if (args) {
result = context.fn(...args)
} else {
result = context.fn()
}
delete context.fn
return result
}
手写一个bind方法
Function.prototype.myBind = function (context,...args) {
if (typeof this!== 'function') {
throw new TypeError('type error')
}
let self = this
let args1 = args || []
return function Fn(...args2) {
if (this instanceof Fn) {
return self.apply(this,args1.concat(args2))
} else {
return self.apply(context,args1.concat(args2))
}
}
}
Function.prototype.myBind2 = function (context,...args) {
if (typeof this!== 'function') {
throw new TypeError('type error')
}
let self = this
let args1 = args || []
return function Fn(...args2) {
return self.apply(context,args1.concat(args2))
}
}
手写一个instanceof方法
function myInstanceof(left,right) {
if (typeof left!== 'object' || left === null) return false
let proto = Object.getPrototypeOf(left)
while (true) {
if (proto === null) return false
if (proto === right.prototype) return true
proto = Object.getPrototypeOf(proto)
}
}
手写一个new方法
function myNew(fn,...args) {
let obj = {}
obj.__proto__ = fn.prototype
let result = fn.apply(obj,args)
return result instanceof Object? result : obj
}
手写一个深拷贝方法
function deepClone(obj,hash = new WeakMap()) {
if (obj.constructor === Date) return new Date(obj)
if (obj.constructor === RegExp) return new RegExp(obj)
if (hash.has(obj)) return hash.get(obj)
let allDesc = Object.getOwnPropertyDescriptors(obj)
let cloneObj = Object.create(Object.getPrototypeOf(obj),allDesc)
hash.set(obj,cloneObj)
for (let key in cloneObj) {
cloneObj[key] = deepClone(obj[key],hash)
}
return cloneObj
}
手写一个浅拷贝方法
function shallowClone(obj) {
if (typeof obj!== 'object') return
let newObj = obj instanceof Array? [] : {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key]
}
}
return newObj
}
手写一个防抖方法
function debounce(fn,wait) {
let timeout = null
return function () {
if (timeout!== null) clearTimeout(timeout)
timeout = setTimeout(fn,wait)
}
}
手写一个节流方法
function throttle(fn,wait) {
let timeout = null
return function () {
if (!timeout) {
timeout = setTimeout(() => {
timeout = null
fn.apply(this,arguments)
},wait)
}
}
}
手写一个Promise方法
function myPromise(fn) {
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
let value = null
let reason = null
let state = PENDING
let onFulfilledCallbacks = []
let onRejectedCallbacks = []
let resolve = (val) => {
if (state === PENDING) {
state = FULFILLED
value = val
setTimeout(() => {
onFulfilledCallbacks.forEach(fn => fn())
})
}
}
let reject = (val) => {
if (state === PENDING) {
state = REJECTED
reason = val
setTimeout(() => {
onRejectedCallbacks.forEach(fn => fn())
})
}
}
try {
fn(resolve,reject)
} catch (e) {
reject(e)
}
this.then = (onFulfilled,onRejected) => {
if (state === FULFILLED) {
onFulfilled(value)
} else if (state === REJECTED) {
onRejected(reason)
} else if (state === PENDING) {
onFulfilledCallbacks.push(() => {
onFulfilled(value)
})
onRejectedCallbacks.push(() => {
onRejected(reason)
})
}
}
}
手写一个Promise.all方法
function myPromiseAll(promises) {
return new myPromise((resolve,reject) => {
let count = 0
let result = []
for (let i = 0; i < promises.length; i++) {
myPromise.resolve(promises[i]).then((data) => {
count++
result[i] = data
if (count === promises.length) {
resolve(result)
}
},(err) => {
reject(err)
})
}
})
}
手写一个Promise.race方法
function myPromiseRace(promises) {
return new myPromise((resolve,reject) => {
for (let i = 0; i < promises.length; i++) {
myPromise.resolve(promises[i]).then((data) => {
resolve(data)
},(err) => {
reject(err)
})
}
})
}
手写一个Promise.allSettled方法
function myPromiseAllSettled(promises) {
return new myPromise((resolve,reject) => {
let count = 0
let result = []
for (let i = 0; i < promises.length; i++) {
myPromise.resolve(promises[i]).then((data) => {
count++
result[i] = {
status: 'fulfilled',
value: data
}
if (count === promises.length) {
resolve(result)
}
},(err) => {
count++
result[i] = {
status: 'rejected',
reason: err
}
if (count === promises.length) {
resolve(result)
}
})
}
})
}
手写一个Promise.any方法
function myPromiseAny(promises) {
return new myPromise((resolve,reject) => {
let count = 0
let result = []
for (let i = 0; i < promises.length; i++) {
myPromise.resolve(promises[i]).then((data) => {
resolve(data)
},(err) => {
count++
result[i] = err
if (count === promises.length) {
reject(new AggregateError(result))
}
})
}
})
}
手写一个Promise.anySettled方法
function myPromiseAnySettled(promises) {
return new myPromise((resolve,reject) => {
let count = 0
let result = []
for (let i = 0; i < promises.length; i++) {
myPromise.resolve(promises[i]).then((data) => {
count++
result[i] = {
status: 'fulfilled',
value: data
}
if (count === promises.length) {
resolve(result)
}
},(err) => {
count++
result[i] = {
status:'rejected',
reason: err
}
if (count === promises.length) {
resolve(result)
}
})
}
})
}
手写一个Promise.finally方法
function myPromiseFinally(onFinally) {
return this.then((value) => {
onFinally()
return value
},(err) => {
onFinally()
throw err
})
}
手写一个Promise.resolve方法
function myPromiseResolve(value) {
return new myPromise((resolve,reject) => {
if (value instanceof myPromise) {
value.then(resolve,reject)
} else {
resolve(value)
}
})
}
手写一个Promise.reject方法
function myPromiseReject(reason) {
return new myPromise((resolve,reject) => {
reject(reason)
})
}
手写一个Promise.catch方法
function myPromiseCatch(onRejected) {
return this.then(null,onRejected)
}