arr.every(fn); all([4, 2, 3], x => x > 1); // trueall([1, 2, 3]); // true復制代?..."/>
溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript 工具函數(shù)大全

發(fā)布時間:2020-07-24 05:29:25 來源:網(wǎng)絡 閱讀:142 作者:wx5d61fdc401976 欄目:開發(fā)技術(shù)
  1. 第一部分:數(shù)組
  2. all:布爾全等判斷
    const all = (arr, fn = Boolean) => arr.every(fn);

all([4, 2, 3], x => x > 1); // true
all([1, 2, 3]); // true
復制代碼2. allEqual:檢查數(shù)組各項相等
const allEqual = arr => arr.every(val => val === arr[0]);

allEqual([1, 2, 3, 4, 5, 6]); // false
allEqual([1, 1, 1, 1]); // true
復制代碼3. approximatelyEqual:約等于
const approximatelyEqual = (v1, v2, epsilon = 0.001) => Math.abs(v1 - v2) < epsilon;

approximatelyEqual(Math.PI / 2.0, 1.5708); // true
復制代碼4. arrayToCSV:數(shù)組轉(zhuǎn)CSV格式(帶空格的字符串)

const arrayToCSV = (arr, delimiter = ',') =>
arr.map(v => v.map(x => "${x}").join(delimiter)).join('\n');

arrayToCSV([['a', 'b'], ['c', 'd']]); // '"a","b"\n"c","d"'
arrayToCSV([['a', 'b'], ['c', 'd']], ';'); // '"a";"b"\n"c";"d"'
復制代碼5. arrayToHtmlList:數(shù)組轉(zhuǎn)li列表
此代碼段將數(shù)組的元素轉(zhuǎn)換為<li>標簽,并將其附加到給定ID的列表中。
const arrayToHtmlList = (arr, listID) =>
(el => (
(el = document.querySelector('#' + listID)),
(el.innerHTML += arr.map(item => &lt;li&gt;${item}&lt;/li&gt;).join(''))
))();

arrayToHtmlList(['item 1', 'item 2'], 'myListID');
復制代碼6. average:平均數(shù)
const average = (...nums) => nums.reduce((acc, val) => acc + val, 0) / nums.length;
average(...[1, 2, 3]); // 2
average(1, 2, 3); // 2
復制代碼7. averageBy:數(shù)組對象屬性平均數(shù)
此代碼段將獲取數(shù)組對象屬性的平均值
const averageBy = (arr, fn) =>
arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => acc + val, 0) /
arr.length;

averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 5
averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 5
復制代碼8. bifurcate:拆分斷言后的數(shù)組
可以根據(jù)每個元素返回的值,使用reduce()和push() 將元素添加到第二次參數(shù)fn中 。
const bifurcate = (arr, filter) =>
arr.reduce((acc, val, i) => (acc[filter[i] ? 0 : 1].push(val), acc), [[], []]);
bifurcate(['beep', 'boop', 'foo', 'bar'], [true, true, false, true]);
// [ ['beep', 'boop', 'bar'], ['foo'] ]
復制代碼9. castArray:其它類型轉(zhuǎn)數(shù)組
const castArray = val => (Array.isArray(val) ? val : [val]);

castArray('foo'); // ['foo']
castArray([1]); // [1]
castArray(1); // [1]
復制代碼10. compact:去除數(shù)組中的無效/無用值
const compact = arr => arr.filter(Boolean);

compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]);
// [ 1, 2, 3, 'a', 's', 34 ]
復制代碼11. countOccurrences:檢測數(shù)值出現(xiàn)次數(shù)
const countOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a), 0);
countOccurrences([1, 1, 2, 1, 2, 3], 1); // 3
復制代碼12. deepFlatten:遞歸扁平化數(shù)組
const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)));

deepFlatten([1, [2], [[3], 4], 5]); // [1,2,3,4,5]
復制代碼13. difference:尋找差異
此代碼段查找兩個數(shù)組之間的差異。

const difference = (a, b) => {
const s = new Set(b);
return a.filter(x => !s.has(x));
};

difference([1, 2, 3], [1, 2, 4]); // [3]
復制代碼14. differenceBy:先執(zhí)行再尋找差異
在將給定函數(shù)應用于兩個列表的每個元素之后,此方法返回兩個數(shù)組之間的差異。
const differenceBy = (a, b, fn) => {
const s = new Set(b.map(fn));
return a.filter(x => !s.has(fn(x)));
};

differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [1.2]
differenceBy([{ x: 2 }, { x: 1 }], [{ x: 1 }], v => v.x); // [ { x: 2 } ]
復制代碼15. dropWhile:刪除不符合條件的值
此代碼段從數(shù)組頂部開始刪除元素,直到傳遞的函數(shù)返回為true。
const dropWhile = (arr, func) => {
while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1);
return arr;
};

dropWhile([1, 2, 3, 4], n => n >= 3); // [3,4]
復制代碼16. flatten:指定深度扁平化數(shù)組
此代碼段第二參數(shù)可指定深度。
const flatten = (arr, depth = 1) =>
arr.reduce((a, v) => a.concat(depth > 1 && Array.isArray(v) ? flatten(v, depth - 1) : v), []);

flatten([1, [2], 3, 4]); // [1, 2, 3, 4]
flatten([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]
復制代碼17. indexOfAll:返回數(shù)組中某值的所有索引
此代碼段可用于獲取數(shù)組中某個值的所有索引,如果此值中未包含該值,則返回一個空數(shù)組。
const indexOfAll = (arr, val) => arr.reduce((acc, el, i) => (el === val ? [...acc, i] : acc), []);

indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
indexOfAll([1, 2, 3], 4); // []
復制代碼18. intersection:兩數(shù)組的交集

const intersection = (a, b) => {
const s = new Set(b);
return a.filter(x => s.has(x));
};

intersection([1, 2, 3], [4, 3, 2]); // [2, 3]
復制代碼19. intersectionWith:兩數(shù)組都符合條件的交集
此片段可用于在對兩個數(shù)組的每個元素執(zhí)行了函數(shù)之后,返回兩個數(shù)組中存在的元素列表。

const intersectionBy = (a, b, fn) => {
const s = new Set(b.map(fn));
return a.filter(x => s.has(fn(x)));
};

intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [2.1]
復制代碼20. intersectionWith:先比較后返回交集
const intersectionWith = (a, b, comp) => a.filter(x => b.findIndex(y => comp(x, y)) !== -1);

intersectionWith([1, 1.2, 1.5, 3, 0], [1.9, 3, 0, 3.9], (a, b) => Math.round(a) === Math.round(b)); // [1.5, 3, 0]
復制代碼21. minN:返回指定長度的升序數(shù)組
const minN = (arr, n = 1) => [...arr].sort((a, b) => a - b).slice(0, n);

minN([1, 2, 3]); // [1]
minN([1, 2, 3], 2); // [1,2]
復制代碼22. negate:根據(jù)條件反向篩選

const negate = func => (...args) => !func(...args);

[1, 2, 3, 4, 5, 6].filter(negate(n => n % 2 === 0)); // [ 1, 3, 5 ]
復制代碼23. randomIntArrayInRange:生成兩數(shù)之間指定長度的隨機數(shù)組
const randomIntArrayInRange = (min, max, n = 1) =>
Array.from({ length: n }, () => Math.floor(Math.random() * (max - min + 1)) + min);

randomIntArrayInRange(12, 35, 10); // [ 34, 14, 27, 17, 30, 27, 20, 26, 21, 14 ]
復制代碼24. sample:在指定數(shù)組中獲取隨機數(shù)
const sample = arr => arr[Math.floor(Math.random() * arr.length)];

sample([3, 7, 9, 11]); // 9
復制代碼25. sampleSize:在指定數(shù)組中獲取指定長度的隨機數(shù)
此代碼段可用于從數(shù)組中獲取指定長度的隨機數(shù),直至窮盡數(shù)組。
使用Fisher-Yates算法對數(shù)組中的元素進行隨機選擇。
const sampleSize = ([...arr], n = 1) => {
let m = arr.length;
while (m) {
const i = Math.floor(Math.random() * m--);
[arr[m], arr[i]] = [arr[i], arr[m]];
}
return arr.slice(0, n);
};

sampleSize([1, 2, 3], 2); // [3,1]
sampleSize([1, 2, 3], 4); // [2,3,1]
復制代碼26. shuffle:“洗牌” 數(shù)組
此代碼段使用Fisher-Yates算法隨機排序數(shù)組的元素。

const shuffle = ([...arr]) => {
let m = arr.length;
while (m) {
const i = Math.floor(Math.random() * m--);
[arr[m], arr[i]] = [arr[i], arr[m]];
}
return arr;
};

const foo = [1, 2, 3];
shuffle(foo); // [2, 3, 1], foo = [1, 2, 3]
復制代碼27. nest:根據(jù)parent_id生成樹結(jié)構(gòu)(阿里一面真題)
根據(jù)每項的parent_id,生成具體樹形結(jié)構(gòu)的對象。
const nest = (items, id = null, link = 'parent_id') =>
items
.filter(item => item[link] === id)
.map(item => ({ ...item, children: nest(items, item.id) }));
復制代碼用法:
const comments = [
{ id: 1, parent_id: null },
{ id: 2, parent_id: 1 },
{ id: 3, parent_id: 1 },
{ id: 4, parent_id: 2 },
{ id: 5, parent_id: 4 }
];
const nestedComments = nest(comments); // [{ id: 1, parent_id: null, children: [...] }]
復制代碼
強烈建議去理解這個的實現(xiàn),因為這是我親身遇到的阿里一面真題:

  1. 第二部分:函數(shù)
  2. attempt:捕獲函數(shù)運行異常
    該代碼段執(zhí)行一個函數(shù),返回結(jié)果或捕獲的錯誤對象。
    onst attempt = (fn, ...args) => {
    try {
    return fn(...args);
    } catch (e) {
    return e instanceof Error ? e : new Error(e);
    }
    };
    var elements = attempt(function(selector) {
    return document.querySelectorAll(selector);
    }, '>_>');
    if (elements instanceof Error) elements = []; // elements = []
    復制代碼2. defer:推遲執(zhí)行
    此代碼段延遲了函數(shù)的執(zhí)行,直到清除了當前調(diào)用堆棧。
    const defer = (fn, ...args) => setTimeout(fn, 1, ...args);

defer(console.log, 'a'), console.log('b'); // logs 'b' then 'a'
復制代碼3. runPromisesInSeries:運行多個Promises
const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve());
const delay = d => new Promise(r => setTimeout(r, d));

runPromisesInSeries([() => delay(1000), () => delay(2000)]);
//依次執(zhí)行每個Promises ,總共需要3秒鐘才能完成
復制代碼4. timeTaken:計算函數(shù)執(zhí)行時間

const timeTaken = callback => {
console.time('timeTaken');
const r = callback();
console.timeEnd('timeTaken');
return r;
};

timeTaken(() => Math.pow(2, 10)); // 1024, (logged): timeTaken: 0.02099609375ms
復制代碼5. createEventHub:簡單的發(fā)布/訂閱模式
創(chuàng)建一個發(fā)布/訂閱(發(fā)布-訂閱)事件集線,有emit,on和off方法。

使用Object.create(null)創(chuàng)建一個空的hub對象。
emit,根據(jù)event參數(shù)解析處理程序數(shù)組,然后.forEach()通過傳入數(shù)據(jù)作為參數(shù)來運行每個處理程序。
on,為事件創(chuàng)建一個數(shù)組(若不存在則為空數(shù)組),然后.push()將處理程序添加到該數(shù)組。
off,用.findIndex()在事件數(shù)組中查找處理程序的索引,并使用.splice()刪除。

const createEventHub = () => ({
hub: Object.create(null),
emit(event, data) {
(this.hub[event] || []).forEach(handler => handler(data));
},
on(event, handler) {
if (!this.hub[event]) this.hub[event] = [];
this.hub[event].push(handler);
},
off(event, handler) {
const i = (this.hub[event] || []).findIndex(h => h === handler);
if (i > -1) this.hub[event].splice(i, 1);
if (this.hub[event].length === 0) delete this.hub[event];
}
});
復制代碼用法:
const handler = data => console.log(data);
const hub = createEventHub();
let increment = 0;

// 訂閱,監(jiān)聽不同事件
hub.on('message', handler);
hub.on('message', () => console.log('Message event fired'));
hub.on('increment', () => increment++);

// 發(fā)布:發(fā)出事件以調(diào)用所有訂閱給它們的處理程序,并將數(shù)據(jù)作為參數(shù)傳遞給它們
hub.emit('message', 'hello world'); // 打印 'hello world' 和 'Message event fired'
hub.emit('message', { hello: 'world' }); // 打印 對象 和 'Message event fired'
hub.emit('increment'); // increment = 1

// 停止訂閱
hub.off('message', handler);
復制代碼6. memoize:緩存函數(shù)
通過實例化一個Map對象來創(chuàng)建一個空的緩存。
通過檢查輸入值的函數(shù)輸出是否已緩存,返回存儲一個參數(shù)的函數(shù),該參數(shù)將被提供給已記憶的函數(shù);如果沒有,則存儲并返回它。
const memoize = fn => {
const cache = new Map();
const cached = function(val) {
return cache.has(val) ? cache.get(val) : cache.set(val, fn.call(this, val)) && cache.get(val);
};
cached.cache = cache;
return cached;
};
復制代碼Ps: 這個版本可能不是很清晰,還有Vue源碼版的:
/**

  • Create a cached version of a pure function.
    */
    export function cached<F: Function> (fn: F): F {
    const cache = Object.create(null)
    return (function cachedFn (str: string) {
    const hit = cache[str]
    return hit || (cache[str] = fn(str))
    }: any)
    }
    復制代碼7. once:只調(diào)用一次的函數(shù)
    const once = fn => {
    let called = false
    return function () {
    if (!called) {
    called = true
    fn.apply(this, arguments)
    }
    }
    };
    復制代碼8. flattenObject:以鍵的路徑扁平化對象
    使用遞歸。

利用Object.keys(obj)聯(lián)合Array.prototype.reduce(),以每片葉子節(jié)點轉(zhuǎn)換為扁平的路徑節(jié)點。
如果鍵的值是一個對象,則函數(shù)使用調(diào)用適當?shù)淖陨韕refix以創(chuàng)建路徑Object.assign()。
否則,它將適當?shù)那熬Y鍵值對添加到累加器對象。
prefix除非您希望每個鍵都有一個前綴,否則應始終省略第二個參數(shù)。

const flattenObject = (obj, prefix = '') =>
Object.keys(obj).reduce((acc, k) => {
const pre = prefix.length ? prefix + '.' : '';
if (typeof obj[k] === 'object') Object.assign(acc, flattenObject(obj[k], pre + k));
else acc[pre + k] = obj[k];
return acc;
}, {});

flattenObject({ a: { b: { c: 1 } }, d: 1 }); // { 'a.b.c': 1, d: 1 }
復制代碼9. unflattenObject:以鍵的路徑展開對象
與上面的相反,展開對象。
const unflattenObject = obj =>
Object.keys(obj).reduce((acc, k) => {
if (k.indexOf('.') !== -1) {
const keys = k.split('.');
Object.assign(
acc,
JSON.parse(
'{' +
keys.map((v, i) => (i !== keys.length - 1 ? "${v}":{ : "${v}":)).join('') +
obj[k] +
'}'.repeat(keys.length)
)
);
} else acc[k] = obj[k];
return acc;
}, {});

unflattenObject({ 'a.b.c': 1, d: 1 }); // { a: { b: { c: 1 } }, d: 1 }
復制代碼這個的用途,在做Tree組件或復雜表單時取值非常舒服。

  1. 第三部分:字符串
    1.byteSize:返回字符串的字節(jié)長度
    const byteSize = str => new Blob([str]).size;

byteSize('

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI