JavaScript》》JS》》ES6》》 数组 自定义属性

自定义属性 数组 是特殊的对象

给数组添加自定义属性是一种利用了"数组也是对象"这一语言特性的技巧。

javascript 复制代码
const myArray = ['a', 'b', 'c']; // 一个普通数组

// 添加自定义属性
myArray.customProperty = 'I am a custom property';
myArray.metadata = { createdBy: 'Alice', creationDate: '2023-10-27' };
myArray.description = 'This array contains some letters';

自定义属性 应用场景

给数组添加自定义属性通常用于存储与整个数组相关的元数据(metadata)或状态信息,而不是数组本身要存储的数据项。

1. 存储元数据(Metadata)

这是最常见的用途。将关于数组的描述信息、来源、状态等与数组数据本身捆绑在一起。

javascript 复制代码
// 模拟从API获取的用户列表数据
const users = ['Alice', 'Bob', 'Charlie'];

// 为这个数据数组添加元数据
users.totalCount = 105; // 服务器上的总用户数,不止当前返回的3个
users.page = 2; // 当前是第几页
users.pageSize = 3; // 每页大小
users.apiEndpoint = '/api/users';

console.log(users);
// 输出: ['Alice', 'Bob', 'Charlie', totalCount: 105, page: 2, pageSize: 3, apiEndpoint: '/api/users']
2. 缓存计算结果(Memoization)

存储一个计算成本高的结果,避免重复计算。

javascript 复制代码
const numbers = [1, 5, 3, 9, 2, 8];

// 计算并缓存最大值
numbers.getMax = function() {
  if (this._cachedMax === undefined) { // 如果还没缓存
    this._cachedMax = Math.max(...this); // 计算并保存
  }
  return this._cachedMax; // 返回缓存的值
};

console.log(numbers.getMax()); // 9 (第一次计算)
console.log(numbers.getMax()); // 9 (第二次直接返回缓存,无需计算)

// 注意:如果数组内容变了,缓存会失效,需要清除或更新
numbers.push(20);
numbers._cachedMax = undefined; // 手动清除缓存
console.log(numbers.getMax()); // 20 (重新计算)
3. 添加自定义方法
javascript 复制代码
const todoList = ['Buy milk', 'Write report', 'Call mom'];

// 添加一个自定义方法
todoList.markAsComplete = function(index) {
  if (this[index]) {
    // 可以在这里添加逻辑,比如修改样式或更新状态对象
    console.log(`Task "${this[index]}" is now complete!`);
  }
};

todoList.markAsComplete(1); // 输出: Task "Write report" is now complete!
4. 标记或状态管理
javascript 复制代码
const dataQueue = ['job1', 'job2', 'job3'];
dataQueue.isProcessing = false; // 标记这个队列是否正在被处理
dataQueue.lastProcessed = null; // 记录最后一个被处理的项目

自定义属性的 陷阱

1. 不会被数组方法迭代

最重要的警告:所有数组的迭代方法(如 forEach, map, filter, for...of, reduce 等)只会遍历数字索引的元素,会完全忽略自定义属性。 for in 可以,

2. 会被 for...in 循环迭代

for...in 循环会遍历对象所有可枚举属性,包括自定义属性。这就是为什么不建议用 for...in 遍历数组的主要原因。

3. JSON 序列化问题

JSON.stringify() 会忽略自定义属性和方法,只序列化数字索引的元素。

更好的替代方案:使用包装对象

javascript 复制代码
// Instead of this:
const usersWithMetadata = ['Alice', 'Bob'];
usersWithMetadata.page = 2;
usersWithMetadata.total = 100;

// Do this: 使用一个对象来包装数组和它的元数据
const userResponse = {
  data: ['Alice', 'Bob'], // 纯数据数组
  pagination: {           // 元数据对象
    page: 2,
    total: 100,
    pageSize: 2
  }
};

// 访问数据和元数据都非常清晰
console.log(userResponse.data[0]); // 'Alice'
console.log(userResponse.pagination.page); // 2
相关推荐
十五年专注C++开发7 小时前
VS2019编译的C++程序,在win10正常运行,在win7上Debug正常运行,Release运行报错0xC0000005,进不了main函数
开发语言·c++·报错c0x0000005
一条咸鱼_SaltyFish7 小时前
[Day13] 微服务架构下的共享基础库设计:contract-common 模块实践
开发语言·人工智能·微服务·云原生·架构·ai编程
隐退山林7 小时前
JavaEE:多线程初阶(一)
java·开发语言·jvm
C_心欲无痕7 小时前
ts - 模板字面量类型与 `keyof` 的魔法组合:`keyof T & `on${string}`使用
linux·运维·开发语言·前端·ubuntu·typescript
Van_captain7 小时前
rn_for_openharmony常用组件_Tabs选项卡
javascript·开源·harmonyos
最贪吃的虎7 小时前
Redis其实并不是线程安全的
java·开发语言·数据库·redis·后端·缓存·lua
赵民勇7 小时前
ES6中的const用法详解
javascript·es6
乾元7 小时前
无线定位与链路质量预测——从“知道你在哪”,到“提前知道你会不会掉线”的网络服务化实践
运维·开发语言·人工智能·网络协议·重构·信息与通信
AC赳赳老秦7 小时前
Unity游戏开发实战指南:核心逻辑与场景构建详解
开发语言·spring boot·爬虫·搜索引擎·全文检索·lucene·deepseek
SunnyDays10118 小时前
如何使用 JAVA 将 PDF 转换为 PPT:完整指南
java·开发语言·pdf转ppt