JavaScript复习-手写题
2021-05-27 02:07:182021-07-05 23:25:14
map、reduce、flatten函数
function myMap(src, cb) {
if (!Array.isArray(src)) throw new TypeError('src must be an array');
const tmp = [];
src.forEach((item) => tmp.push(cb(item)));
return tmp;
}
function myReduce(src, cb, initialValue) {
if (!Array.isArray(src)) throw new TypeError('src must be an array');
let init = initialValue || src[0];
const tmp = initialValue ? src : src.slice(1);
tmp.forEach((item, index) => {
init = cb(init, item, index, tmp);
});
return init;
}
const flatten = (arr, dep = 1) => (dep > 0
? arr.reduce((pre, cur) => pre.concat(Array.isArray(cur) ? flatten(cur, dep - 1) : cur), [])
: arr.slice());
curry函数
function myCurry(fn) {
return (...args) => (fn.length === args.length
? fn.call(null, ...args)
: fn.bind(null, ...args));
}
异步求和
原文地址: 一道字节笔试题,实现一个异步求和函数
提供一个异步 add 方法如下,需要实现一个await sum(...args)
函数
function asyncAdd(a, b, callback) {
setTimeout(() => {
callback(null, a + b);
}, 1000);
}
function sum2(a, b) {
return new Promise((resolve, reject) => {
asyncAdd(a, b, (err, res) => {
if (err) reject(err);
else resolve(res);
});
});
}
function sum(...args) {
if (args.length === 0) return Promise.resolve(0);
if (args.length === 1) return Promise.resolve(args[0]);
return new Promise((resolve) => {
args.reduce(
(pre, cur) => pre.then((total) => sum2(total, cur)),
Promise.resolve(0),
).then(resolve);
});
}
async function sumTmp(...args) {
if (args.length === 1) return Promise.resolve(args[0]);
const res = args.reduce(async (a, b) => sum2(await a, b), Promise.resolve(0));
return res;
}
async function performanceSum(...args) {
const tmp = JSON.parse(JSON.stringify(args));
const { length } = tmp;
if (length === 1) return Promise.resolve(tmp[0]);
const resultArray = [];
if (length % 2) tmp.push(0);
for (let i = 0; i < tmp.length / 2; i += 1) {
resultArray.push([tmp[i * 2], tmp[i * 2 + 1]]);
}
const res = await Promise.all(resultArray.map(([a, b]) => sum2(a, b)));
return performanceSum(...res);
}
rgb(255, 255, 255)转#ffffff
function rgb2hex(rgb) {
const [r, g, b] = rgb.match(/\d+/g);
return `#${
[r, g, b].map((item) => (+item).toString(16).padStart(2, '0')).join('')
}`;
}
Promise.all
function promiseAll(promises) {
if (!promises[Symbol.iterator]) throw new TypeError('promises must be iterable');
return new Promise((resolve, reject) => {
const resolvedPromises = [];
promises.forEach((promise) => Promise.resolve(promise).then((res) => {
resolvedPromises.push(res);
if (resolvedPromises.length === promises.length) resolve(resolvedPromises);
}, reject));
});
}
Promise.allSettled
const PromiseStatus = {
resolved: 'fulfilled',
rejected: 'rejected',
};
function promiseAllSettled1(promises) {
if (!promises[Symbol.iterator]) throw new TypeError('promises must be iterable');
const onResolve = (value) => ({ status: PromiseStatus.resolved, value });
const onReject = (reason) => ({ status: PromiseStatus.rejected, reason });
return Promise.all(promises.map((promise) => Promise.resolve(promise).then(onResolve, onReject)));
}
function promiseAllSettled2(promises) {
if (!promises[Symbol.iterator]) throw new TypeError('promises must be iterable');
return new Promise((resolve) => {
const res = [];
promises.map((promise) => Promise.resolve(promise).then((value) => {
res.push({ status: PromiseStatus.resolved, value });
if (res.length === promises.length) resolve(res);
}, (reason) => {
res.push({ status: PromiseStatus.rejected, reason });
if (res.length === promises.length) resolve(res);
}));
});
}
Promise.any
function promiseAny(promises) {
if (!promises[Symbol.iterator]) throw new TypeError('promises must be iterable');
return new Promise((resolve, reject) => {
const { length } = promises;
const rejectedPromises = [];
promises.forEach((promise) => Promise.resolve(promise).then(resolve, (err) => {
rejectedPromises.push(err);
if (rejectedPromises.length === length) reject(rejectedPromises);
}));
});
}
shallowEqual
function shallowEqual(obj1, obj2) {
if (obj1 === obj2) return true;
if (
typeof obj1 !== 'object'
|| obj1 === null
|| typeof obj2 !== 'object'
|| obj2 === null
) return false;
if (Reflect.ownKeys(obj1).length !== Reflect.ownKeys(obj2).length) return false;
const keys = Reflect.ownKeys(obj1);
for (let i = 0; i < keys.length; i += 1) {
if (obj1[keys[i]] !== obj2[keys[i]]) return false;
}
return true;
}
shuffle
const shuffle = (list) => list.sort(() => Math.random() - 0.5)