碎片時間學編程「04」:可以將對象用作數組而不在?JavaScript?中修改它嗎?

前幾天,我偶然發(fā)現了一些代碼,我需要將一個對象作為常規(guī)數組處理幾次。這當然可以使用Object.keys(),Object.values()或來實現Object.entries(),但它很快就變得冗長了。

所以我想我可以創(chuàng)建某種包裝器來接收一個對象并為它定義一些類似數組的行為。我主要需要Array.prototype.map(),Array.prototype.find(). 使用方法創(chuàng)建所有這些功能都非常簡單 ??梢赃@么說,唯一棘手的部分是讓對象表現得像一個可迭代對象,這需要使用Array.prototype.includes()和Array.prototype.lengthObjectSymbol.iterator生成器函數。

將新功能注入到對象中可以像添加方法一樣簡單。這種方法的缺點是它們將成為實際對象的一部分,這可能是有問題的。如果我們想在少數對象上應用它,這也不是很可重用,這也無濟于事。

輸入Proxy 對象,它是 JavaScript 開發(fā)人員工具帶中鮮為人知的工具之一,但卻是一個非常強大的工具。它用于攔截對象的某些操作,例如屬性查找、賦值等。在這種情況下,它可以巧妙地將所需的功能包裝到一個圍繞對象創(chuàng)建代理的函數中。

最終代碼(可能是)可以在下面的示例中看到。它實現了我需要的功能,以及一些更好的Array測量方法:

const toKeyedArray = obj => {

? const methods = {

? ? map(target) {

? ? ? return callback =>

? ? ? ? Object.keys(target).map(key => callback(target[key], key, target));

? ? },

? ? reduce(target) {

? ? ? return (callback, accumulator) =>

? ? ? ? Object.keys(target).reduce(

? ? ? ? ? (acc, key) => callback(acc, target[key], key, target),

? ? ? ? ? accumulator

? ? ? ? );

? ? },

? ? forEach(target) {

? ? ? return callback =>

? ? ? ? Object.keys(target).forEach(key => callback(target[key], key, target));

? ? },

? ? filter(target) {

? ? ? return callback =>

? ? ? ? Object.keys(target).reduce((acc, key) => {

? ? ? ? ? if (callback(target[key], key, target)) acc[key] = target[key];

? ? ? ? ? return acc;

? ? ? ? }, {});

? ? },

? ? slice(target) {

? ? ? return (start, end) => Object.values(target).slice(start, end);

? ? },

? ? find(target) {

? ? ? return callback => {

? ? ? ? return (Object.entries(target).find(([key, value]) =>

? ? ? ? ? callback(value, key, target)

? ? ? ? ) || [])[0];

? ? ? };

? ? },

? ? findKey(target) {

? ? ? return callback =>

? ? ? ? Object.keys(target).find(key => callback(target[key], key, target));

? ? },

? ? includes(target) {

? ? ? return val => Object.values(target).includes(val);

? ? },

? ? keyOf(target) {

? ? ? return value =>

? ? ? ? Object.keys(target).find(key => target[key] === value) || null;

? ? },

? ? lastKeyOf(target) {

? ? ? return value =>

? ? ? ? Object.keys(target)

? ? ? ? ? .reverse()

? ? ? ? ? .find(key => target[key] === value) || null;

? ? },

? };

? const methodKeys = Object.keys(methods);

? const handler = {

? ? get(target, prop, receiver) {

? ? ? if (methodKeys.includes(prop)) return methods[prop](...arguments);

? ? ? const [keys, values] = [Object.keys(target), Object.values(target)];

? ? ? if (prop === 'length') return keys.length;

? ? ? if (prop === 'keys') return keys;

? ? ? if (prop === 'values') return values;

? ? ? if (prop === Symbol.iterator)

? ? ? ? return function* () {

? ? ? ? ? for (value of values) yield value;

? ? ? ? ? return;

? ? ? ? };

? ? ? else return Reflect.get(...arguments);

? ? },

? };

? return new Proxy(obj, handler);

};

// Object creation

const x = toKeyedArray({ a: 'A', b: 'B' });

// Accessing properties and values

x.a;? ? ? ? ? // 'A'

x.keys;? ? ? // ['a', 'b']

x.values;? ? // ['A', 'B']

[...x];? ? ? // ['A', 'B']

x.length;? ? // 2

// Inserting values

x.c = 'c';? ? // x = { a: 'A', b: 'B', c: 'c' }

x.length;? ? // 3

// Array methods

x.forEach((v, i) => console.log(`${i}: ${v}`)); // LOGS: 'a: A', 'b: B', 'c: c'

x.map((v, i) => i + v);? ? ? ? ? ? ? ? ? ? ? ? // ['aA', 'bB, 'cc]

x.filter((v, i) => v !== 'B');? ? ? ? ? ? ? ? ? // { a: 'A', c: 'c' }

x.reduce((a, v, i) => ({ ...a, [v]: i }), {}); // { A: 'a', B: 'b', c: 'c' }

x.slice(0, 2);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // ['A', 'B']

x.slice(-1);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // ['c']

x.find((v, i) => v === i);? ? ? ? ? ? ? ? ? ? ? // 'c'

x.findKey((v, i) => v === 'B');? ? ? ? ? ? ? ? // 'b'

x.includes('c');? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // true

x.includes('d');? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // false

x.keyOf('B');? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 'b'

x.keyOf('a');? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // null

x.lastKeyOf('c');? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 'c'

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容