1. 手写instanseof方法
要求
如果是基础类型那么直接返回false,否则顺着原型链进行比对,一直到原型链为null
源码
function instance_of(L, R) {
const baseType = ['string', 'number', 'boolean', 'undefined', 'symbol', 'bigint']
if (baseType.includes(typeof (L))) return false
let RP = R.prototype
L = L.__proto__
while (true) {
if (L === null) return false
else if (L === RP) return true
else L = L.__proto__
}
}
测试
class Person {
constructor(_name, _age) {
this.name = _name
this.age = _age
}
}
let person = new Person('name', 0)
console.log(instance_of(person, Person))
console.log(instance_of(person, Array))
console.log(instance_of([], Array))
测试结果
true
false
true
2. 手写new方法
说明
创建一个新对象,通过apply或call等方法将this绑定到新对象上。
源码
function _new (ctx, ...arg) {
const obj = {}
obj.__proto__ = ctx.prototype
const res = ctx.apply(obj, arg)
return res instanceof Object ? res : obj
}
测试
function Bar(_name, _age) {
this.name = _name
this.age = _age;
}
let b = _new(Bar, 'name', 20)
console.log(b)
测试结果
Bar { name: 'name', age: 20 }
3. 手写map方法
说明
遍历数组并利用参数中的函数生成一个新的数组
源码
// _this默认为本身
Array.prototype.myMap = function (fn, _this = this) {
let arr = []
// 遍历数组,循环对元素执行回调函数
for (let index in this) {
// 执行回调函数时绑定this,并将结果push进新数组
arr.push(fn.call(_this, this[index], index, this))
}
// 返回新数组
return arr
}
// 设置新增原型为不可枚举,不会被for...in遍历出来
Object.defineProperty(Array.prototype, 'myMap', {
enumerable: false
})
测试
// 测试
let arr = [1, 2, 3]
let newarr = arr.myMap(function (item, index, _this) {
return item + ' ' + index + ' ' + _this[index] + ' ' + this[index]
}, [7, 8, 9])
console.log(newarr)
测试结果
// [ '1 0 1 7', '2 1 2 8', '3 2 3 9' ]
4. 手写一个Promise
说明
实现基本的Promise方法
源代码
const reslovePromise = (promise2, x, reslove, reject) => {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof iPromise) {
x.then.call(x, res => {
reslovePromise(promise2, res, reslove, reject)
}, err => {
reject(err)
})
} else {
reslove(x)
}
}
class iPromise {
constructor(executor) {
this.state = 'pending'
this.value = undefined
this.reason = undefined
this.onResolvedCallbacks = []
this.onRejectedCallbacks = []
const reslove = value => {
if (value instanceof iPromise) {
return value.then(reslove, reject)
}
setTimeout(() => {
if (this.state === 'pending') {
this.state = 'fulfilled'
this.value = value
this.onResolvedCallbacks.forEach(fn => fn())
}
}, 0)
}
const reject = reason => {
setTimeout(() => {
if (this.state === 'pending') {
this.state = 'rejected'
this.reason = reason
this.onRejectedCallbacks.forEach(fn => fn())
}
}, 0)
}
executor(reslove, reject)
}
then(onFulfilled, onRejected) {
const promise2 = new iPromise((reslove, reject) => {
if (this.state === 'pending') {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
const x = onFulfilled(this.value)
reslovePromise(promise2, x, reslove, reject)
}, 0)
})
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
const x = onRejected(this.reason)
reslovePromise(promise2, x, reslove, reject)
}, 0)
})
}
if (this.state === 'fulfilled') {
setTimeout(() => {
const x = onFulfilled(this.value)
reslovePromise(promise2, x, reslove, reject)
}, 0)
}
if (this.state === 'rejected') {
setTimeout(() => {
const x = onRejected(this.reason)
reslovePromise(promise2, x, reslove, reject)
}, 0)
}
})
return promise2
}
static reslove(value) {
return new iPromise((reslove, reject) => {
reslove(value)
})
}
static reject(reason) {
return new iPromise((reslove, reject) => {
reject(reason)
})
}
static race(promises) {
return new iPromise((resolve, reject) => {
promises.forEach(promise => {
promise.then(resolve, reject)
})
})
}
static all(promises) {
return new Promise((res, rej) => {
var arr = []
var times = 0;
function processResult(index, result) {
arr[index] = result
times++;
if (times == promiseArr.length) {
res(arr)
}
}
for (let i = 0; i < promises.length; i++) {
var oPromise = promises[i];
if (typeof oPromise.then == 'function') {
oPromise.then(function (val) {
processResult(i, val)
}, function (reason) {
rej(reason)
})
} else {
processResult(i, oPromise)
}
}
})
}
}
网友评论