[JS-Basics] Implementation
目錄
- Promise.all
- Promise.race
- debounce
- throttle
- Array method(Reduce, map, filter, forEach,every, some)
- shallow copy
- deep copy
- memoize function
- Lodash's get()
- instanceof
Promise.all
function promiseAll(values) {
if (!Array.isArray(values)) return;
return new Promise((resolve, reject) => {
let results = [];
let completed = 0;
values.forEach((value, index) => {
Promise.resolve(value)
.then((result) => {
results[index] = result; // 確保回傳的Promise中,value的順序是對的!
completed += 1;
//如果成功的話就會回傳resolve
if (completed == values.length) {
resolve(results);
}
})
.catch((err) => reject(err));
});
});
}
Promise.race
const PromiseRace = (values) => {
return new Promise((resolve, reject) => {
for (const item of values) {
//第一個完成的會直接回傳
Promise.resolve(item).then(resolve).catch(reject);
}
});
};
debounce
function debounce(fn, delay = 500) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => {
fn(...args);
}, delay);
};
}
throttle
function throttle(fn, delay = 500) {
let timer = null;
return (...args) => {
if (timer) return;
timer = setTimeout(() => {
fn(...args);
timer = null;
}, delay);
};
}
Array method
Array.prototype.reduce
Array.prototype.myReduce = function (callback, initialValue) {
let init = initialValue || this[0];
let index = initialValue ? 0 : 1;
for (let i = index; i < this.length; i++) {
init = callback(init, this[i]);
}
return init;
};
Array.prototype.map
Array.prototype.myMap = function (callback) {
const result = [];
for (let i = 0; i < this.length; i++) {
result.push(callback(this[i], i, this));
}
return result;
};
Array.prototype.filter
Array.prototype.myFilter = function (callback) {
const resultArray = [];
for (let i = 0; i < this.length; i++) {
if (!!callback(this[i], i, this)) {
resultArray.push(this[index]);
}
}
return resultArray;
};
Array.prototype,forEach
Array.prototype.myEach = function myEach(callback) {
for (let i = 0; i < this.length; i++) {
callback(this[i], i, this);
}
};
Array.prototype.every
Array.prototype.myEvery = function myEvery(callback, thisArg) {
for (var i = 0; i < this.length; i++) {
if (!callback(this[i], i, this)) return false;
}
return true;
};
Array.prototype.some
Array.prototype.mySome = function mySome(callback, thisArg) {
for (var i = 0; i < this.length; ++i) {
if (callback(this[i], i, this)) return true;
}
return false;
};
shallow copy
array
- spread operator
- Array.prototype.slice()
object
- spread operator
- Object.assign
- lodash's _.clone
deep copy
- JSON.parse(JSON.stringify())
- lodash _.cloneDeep
- structuredClone(Node 17):
memoize function
function memoizeMap(fn) {
let map = new Map();
return function (...args) {
let key = JSON.stringify(args);
if (map.has(key)) {
return map.get(key);
} else {
let value = fn(...args);
map.set(key, value);
return value;
}
};
}
let testFn = (foo) => foo + 999;
let memoizeMapFn = memoizeMap(testFn);
memoizeMapFn(1); // map對arg 1生成緩存
memoizeMapFn(1); // 取緩存結果
memoizeMapFn(1); // 取緩存結果
memoizeMapFn(2); // map對arg 2生成緩存
memoizeMapFn(2); // 取緩存結果
memoizeMapFn(1); // 取緩存結果
lodash's get
//lodash中的get使用方法
const obj = {
a: {
b: {
c: [1, 2, 3],
},
},
};
get(obj, "a.b.c"); // [1,2,3]
get(obj, "a.b.c.0"); // 1
get(obj, "a.b.c[1]"); // 2
get(obj, ["a", "b", "c", "2"]); // 3
get(obj, "a.b.c[3]"); // undefined
get(obj, "a.c", "bfe"); // 'bfe'
/**
* @param {object} source
* @param {string | string[]} path
* @param {any} [defaultValue]
* @return {any}
*/
function get(source, path, defaultValue = undefined) {
const arrPath = typeof path === "string" ? path.match(/[^\[\]\.]+/g) : path;
if (!(arrPath && arrPath.length)) return;
const result = arrPath.reduce((obj, key) => obj && obj[key], source);
return result || defaultValue;
}
instanceof
function _instanceof(L, R) {
if (typeof L !== "object") return false;
L = L.__proto__;
R = R.prototype;
while (true) {
if (L === null) return false;
if (L === R) return true;
L = L.__proto__;
}
}