这里总结一下一些前端常见手写。 我把我之前写的文章进行一个总结放在一起。以前是在其他博客网站上写的。
这里直接看代码
bind
Function.prototype.bind = function (...args) {
if (typeof this !== 'function') {
throw new TypeError(`${JSON.stringify(this)} is not a function`)
}
const func = this;
const [This, ...pervArgs] = args;
return function (...rest) {
if (new.target) {
return new func(...pervArgs, ...rest);
}
return func.apply(This, pervArgs.concat(rest));
}
}
call
Function.prototype.myCall = function (_this, ...args) {
// call方法可以用来改变方法调用的this指向
const func = this;
if (typeof func !== "function") {
// 类型判断
throw TypeError("this is not a function");
}
if (typeof _this !== "object") {
// 如果绑定的this不是一个对象
_this = Object(_this);
}
const random = Math.random().toString(16).substring(2);
Object.defineProperty(_this, "fn" + random, {
value: func,
enumerable: false,
});
const result = _this["fn" + random](...args);
// 这里在_this上添加了一个属性,需要删除
delete _this.fn;
return result;
};
apply
Function.prototype.myApply = function (_this, args) {
const func = this;
if (typeof func !== "function") {
// 类型判断
throw TypeError("this is not a function");
}
if (!Array.isArray(args)) {
throw TypeError("arg is not a array");
}
return func.myCall(_this, ...args);
};
Promise.allSettled
Promise.myAllSettled = function (proms) {
return new Promise((resolve, reject) => {
let resolvedCount = 0;
let count = 0;
const results = [];
for (const prom of proms) {
let i = count;
count++;
Promise.resolve(prom)
.then(
(data) => {
resolvedCount++;
results[i] = {
status: "fullfilled",
value: data,
};
},
(reason) => {
resolvedCount++;
results[i] = {
status: "rejected",
reason,
};
}
)
.finally(() => {
if (resolvedCount >= count) {
resolve(results);
}
});
}
});
};
Promise.finally
Promise.prototype.finally = function (onSettled) {
return this.then(data=>{ // then返回的也是一个Promise对象
onSettled(); // 执行回调,但不传递数据
return data; // 保证返回的Promise对象的数据一致
},reason=>{
onSettled();
throw reason; // 保证返回的Promise对象的数据状态一致
})
}
Promise.all
Promise.all = function (proms) {
return new Promise((resolve, reject) => {
try {
let count = 0; // 有多少个proms
let resolvedCount = 0; // 有多少个promise已经resolve
let results = [] // resolve的结果是一个数组
for (const pro of proms) { // proms不一定是数组,应该是迭代器
let curIndex = count; // 记录这个promise resolve后在返回数组的下标
count++;
Promise.resolve(pro).then(data => { // 有可能不是一个promise,所以需要包装一下
results[curIndex] = data;
resolvedCount++;
if (count === resolvedCount) {
// 所有promise已经resolved,触发返回Promise的resolve
resolve(results);
}
}, reject) // 有一个错误了就调用reject
}
if (count === 0) {
// 有可能传进来的是一个空数组
resolve(results);
}
} catch (error) {
reject(error) // 如果过程中出现错误,直接触发返回promise的reject
}
})
}