怎么把一个对象当做数组使用

怎么把一个对象当做数组使用?对象当
我们知道在JS中对象和数组的操作方式是不一样的,但是数组使用我们可以通过封装,给对象加一层包装器,对象当让它可以和数组拥有同样的数组使用使用方式。我们主要借助Object.keys()、对象当Object.values()、数组使用Object.entries()、对象当Proxy。数组使用
Object.keys
看一下MDN上的对象当解释:
Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的数组使用排列顺序和正常循环遍历该对象时返回的顺序一致。
也就是对象当Object.keys可以获取对象的所有属性名,并生成一个数组。数组使用
var obj = { a: 0,对象当 b: 1, c: 2 };
console.log(Object.keys(obj));
// console: [a, b, c]Object.values
看一下MDN上的解释:
Object.values()方法返回一个给定对象自身的所有可枚举属性值的数组,值的数组使用顺序与使用for...in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
Object.values()返回一个数组,对象当元素是b2b供应网对象上找到的可枚举属性值。
var obj = { foo: bar, baz: 42 };
console.log(Object.values(obj));
// [bar, 42]Object.entries
看一下MDN上的解释:
Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。
Object.entries()返回一个数组,元素是由属性名和属性值组成的数组。
const obj = { foo: bar, baz: 42 };
console.log(Object.entries(obj));
// [ [foo, bar], [baz, 42] ]Proxy
Proxy是JS最新的对象代理方式,用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
使用Proxy可以封装对象的原始操作,在执行对象操作的时候,会经过Proxy的处理,这样我们就可以实现数组操作命令。
基础 get 示例
const handler = {
get: function(obj, prop) {
return prop in obj ? obj[prop] : 37;
}
}
const p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;
console.log(p.a, p.b)
console.log(c in p, p.c)以上示例的中,当对象中不存在属性名时,默认返回值为37。站群服务器
无操作转发代理
使用Proxy包装原生对象生成一个代理对象p,对代理对象的操作会转发到原生对象上。
let target = {};
let p = new Proxy(target, {});
p.a = 37; // 操作转发到目标
console.log(target.a); // 37. 操作已经被正确地转发我们要实现以下几个函数:forEach、map、filter、reduce、slice、find、findKey、includes、keyOf、lastKeyOf。
实现数组函数
forEach
数组中的forEach函数定义:arr.forEach(callback(currentValue [, index [, array]])[, thisArg])。
数组中的forEach需要传入一个函数,函数的第一个参数是当前操作的元素值,第二个参数是当前操作的元素索引,第三个参数是正在操作的对象。
对于对象,我们将参数定为:currentValue、key、target。我们可以使用Object.keys来遍历对象。
Object.keys(target).forEach(key => callback(target[key], key, target))这里需要target和callback参数,b2b信息网我们通过函数封装一下。
function forEach(target, callback) {
Object.keys(target).forEach(key => callback(target[key], key, target))
}这样我们就可以使用以下方式调用:
const a = {a: 1, b: 2, c: 3}
forEach(a, (v, k) => console.log(`${k}-${v}`))
// a-1
// b-2
// c-3通过Proxy封装:
const handler = {
get: function(obj, prop) {
return forEach(obj)
}
}
const p = new Proxy(a, handler)
p.forEach((v, k) => console.log(`${k}-${v}`))以上方式当然是不行的,我们主要看最后一句,其执行方式和数组的forEach完全相同,我们在调用Proxy封装的对象时,获取数据时,会调用get函数,第一个参数为原生对象,第二个参数为属性名-forEach,在这里就要修改我们的forEach函数了。首先p.forEach的参数是一个函数,因此我们代理对象的返回值需要接收一个函数作为参数,因此修改如下:
function forEach(target) {
return (callback) => Object.keys(target).forEach(key => callback(target[key], key, target))
}因此完成代码为:
function forEach(target) {
return (callback) => Object.keys(target).forEach(key => callback(target[key], key, target))
}
const handler = {
get: function(obj, prop) {
return forEach(obj)
}
}
const a = {a: 1, b: 2, c: 3}
const p = new Proxy(a, handler)
p.forEach((v, k) => console.log(`${k}-${v}`))
// a-1
// b-2
// c-3我们应该把以上代码封装为模块,方便对外使用:
const toKeyedArray = (obj) => {
const methods = {
forEach(target) {
return (callback) => Object.keys(target).forEach(key => callback(target[key], key, target));
}
}
const methodKeys = Object.keys(methods)
const handler = {
get(target, prop) {
if (methodKeys.includes(prop)) {
return methods[prop](target)
}
return Reflect.get(...arguments)
}
}
return new Proxy(obj, handler)
}
const a = { a: 1, b: 2, c: 3}
const p = toKeyedArray(a)
p.forEach((v, k) => console.log(`${k}-${v}`))以上是forEach的实现和封装,其他函数的实现方式类似。
全部源码如下:
const toKeyedArray = (obj) => {
const methods = {
forEach(target) {
return (callback) => Object.keys(target).forEach(key => callback(target[key], key, target));
},
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) {
if (methodKeys.includes(prop)) {
return methods[prop](target)
}
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;
};
return Reflect.get(...arguments)
}
}
return new Proxy(obj, handler)
}
const x = toKeyedArray({ a: A, b: B });
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相关文章
毛桃Pe系统教程(打造专属于你的电脑系统,让操作更高效、更顺心)
摘要:在日常使用电脑的过程中,我们经常会遇到各种各样的问题,例如系统崩溃、病毒感染等。而且,很多时候我们想要个性化定制自己的电脑系统,以适应个人的需求和爱好。而毛桃Pe系统正是为了解决这...2025-11-05
比较不同的编程语言如何解决同一个问题是一个很有趣的事情,也很有指导意义。接下来,我们就来讲一讲如何用 Python 来解决。在我这一系列的第一篇文章里,我描述了这样子的一个问题,如何将一大批的救助物资2025-11-05
如何使用第三方日志记录提供程序替代.NET Core中的内置程序
本文转载自微信公众号「UP技术控」,作者 conan5566。转载本文请联系UP技术控公众号。.NET Core 支持适用于各种内置和第三方日志记录提供程序的日志记录 API。 先来看下如何将日志记录2025-11-05
安全传输层协议 TLS,以前称为 SSL(Secure Sockets Layer) ,由于HTTPS的推出受到了很多人的欢迎。但是正如TLS的名称 Transport Layer Security2025-11-05MotoZXT1605(探索MotoZXT1605的创新功能和出色性能)
摘要:作为摩托罗拉旗下的一款旗舰手机,MotoZXT1605凭借其创新的设计和卓越的性能在市场上引起了极大的关注。本文将深入探讨这款手机的功能和性能,为读者揭示其独特之处和优势。...2025-11-05
1 前言Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库 Apache Lucene™ 基础之上。那么如何实现 Elasticsearch和 Python 的对接成为我们所关2025-11-05

最新评论