当前位置: 首页 > news >正文

JavaScript:10个数组方法/属性

1. length (属性)

深度解析:
  • 技术原理:动态反映数组当前元素数量,基于最大索引值+1

  • 特殊行为

    • 设置小于当前长度:截断数组(不可逆操作)

    • 设置大于当前长度:创建空位(empty slots),访问返回undefined但迭代跳过

    • 空位与undefined的区别:[,1] vs [undefined,1]

 

使用场景:
1.快速清空数组(性能最优):
const data = [/* 大量数据 */];
data.length = 0; // 比 data = [] 更高效
2.数组截断
const logs = ['log1', 'log2', 'log3', 'log4'];
// 只保留最后2条日志
logs.length = Math.min(logs.length, 2);
3.预分配大数组(谨慎使用):
const pixelData = new Array(1920*1080); // 创建200万空位
// 后续填充数据(比动态push高效)
注意事项:
// 空位陷阱示例
const sparseArr = [1, , 3];
console.log(sparseArr.length); // 3
console.log(sparseArr[1]);     // undefined// forEach跳过空位
sparseArr.forEach(v => console.log(v)); // 只输出1和3// 解决:显式填充undefined
const denseArr = Array.from(sparseArr); // [1, undefined, 3]

2. push()

深度解析:
  • 技术原理:修改原数组,在末尾添加元素,返回新长度

  • 性能特点:O(1)时间复杂度(摊销常数时间)

 使用场景:
1.动态数据收集
const userInputs = [];
inputElement.addEventListener('change', (e) => {userInputs.push(e.target.value);
});
 2.栈操作(LIFO)
const historyStack = [];
function doAction(action) {historyStack.push(action);// 执行操作...
}
3.批量添加元素
// 优于多次调用push
const newItems = ['item4', 'item5', 'item6'];
items.push(...newItems); // 扩展运算符
最佳实践:
// 避免在循环中连续push
// 反例(性能差):
for(let i=0; i<10000; i++) {arr.push(i);
}// 正例(预分配):
const arr = new Array(10000);
for(let i=0; i<10000; i++) {arr[i] = i;
}

3. pop()

深度解析:
  • 技术原理:移除最后一个元素并返回,修改原数组长度

  • 边界情况:空数组调用返回undefined

使用场景:
1.栈操作(LIFO)
function undo() {if(historyStack.length > 0) {const lastAction = historyStack.pop();revertAction(lastAction);}
}
2.处理任务队列
while(taskQueue.length > 0) {const task = taskQueue.pop();executeTask(task);
}
3.递归处理嵌套结构
function flatten(arr) {const result = [];while(arr.length) {const next = arr.pop();if(Array.isArray(next)) {arr.push(...next);} else {result.push(next);}}return result.reverse();
}
注意事项:
// 不可逆操作警告
const original = [1, 2, 3];
const last = original.pop(); 
console.log(original); // [1,2] - 永久改变

4. shift()

深度解析:
  • 技术原理:移除首元素并返回,所有后续元素前移

  • 性能问题:O(n)时间复杂度,大数据量慎用

 

使用场景:
1.队列处理(FIFO)
const messageQueue = [];// 入队
socket.on('message', msg => messageQueue.push(msg));// 处理队列
setInterval(() => {if(messageQueue.length > 0) {processMessage(messageQueue.shift());}
}, 100);
2.流式数据处理
while(dataStream.length) {const packet = dataStream.shift();parsePacket(packet);
}
性能优化:
// 替代方案:使用索引指针
class Queue {constructor() {this.items = {};this.front = 0;this.rear = 0;}enqueue(item) {this.items[this.rear++] = item;}dequeue() {if(this.front >= this.rear) return null;const item = this.items[this.front];delete this.items[this.front++];return item;}
}

5. unshift()

深度解析:
  • 技术原理:在数组开头添加元素,所有现有元素后移

  • 性能问题:O(n)时间复杂度,大数据量避免使用

使用场景:
1.优先级队列: 
const tasks = [];function addTask(task, isHighPriority) {if(isHighPriority) {tasks.unshift(task); // 高优先级插队} else {tasks.push(task);}
}
2.时间线展示(最新在前)
const timeline = [];function addEvent(event) {timeline.unshift(event); // 新事件在开头if(timeline.length > 100) timeline.pop(); // 限制长度
}
替代方案:
// 使用reverse + push 替代
const arr = [3,4];
arr.reverse().push(1,2);
arr.reverse(); // [1,2,3,4]// 大数据量使用链表
class LinkedList {// 实现链表结构...
}

6. forEach()

深度解析:
  • 技术原理:为每个元素执行回调(元素,索引,原数组)

  • 重要特性

    • 无法用break中断

    • 空位会被跳过

    • 不等待异步操作

使用场景:
1.DOM批量操作
const buttons = document.querySelectorAll('button');
buttons.forEach(btn => {btn.addEventListener('click', handleClick);
});
2.执行副作用操作
const users = [/*...*/];
users.forEach(user => {saveToLocalStorage(user.id, user);
});
异步处理:
// 错误:不会等待
items.forEach(async item => {await processItem(item); // 不会顺序执行
});// 正确:使用for...of
async function processAll() {for(const item of items) {await processItem(item);}
}

7. map()

深度解析:
  • 技术原理:创建新数组,每个元素是回调返回值

  • 核心特性

    • 不修改原数组(纯函数)

    • 保持数组长度不变

    • 跳过空位

使用场景:
1.数据格式转换
const apiResponse = [{ id: 1, name: 'Alice' },{ id: 2, name: 'Bob' }
];const userIds = apiResponse.map(user => user.id); // [1,2]
2.JSX列表渲染
function UserList({ users }) {return (<ul>{users.map(user => (<li key={user.id}>{user.name}</li>))}</ul>);
}
3.数学计算
const temperaturesC = [0, 25, 100];
const temperaturesF = temperaturesC.map(c => c * 9/5 + 32);
最佳实践:
// 避免在map中产生副作用
// 反例:
items.map(item => {saveItem(item); // 副作用操作return item.id;
});// 正例:使用forEach处理副作用
const ids = [];
items.forEach(item => {saveItem(item);ids.push(item.id);
});

8. filter()

深度解析:
  • 技术原理:返回回调返回truthy的元素组成的新数组

  • 重要特性

    • 不修改原数组

    • 结果数组长度 <= 原数组

    • 跳过空位

使用场景: 
1.数据筛选
const products = [/*...*/];
const availableProducts = products.filter(p => p.stock > 0);
2.搜索功能
function search(query) {return items.filter(item => item.name.toLowerCase().includes(query.toLowerCase()));
}
3.数据清理
const userInput = ['', 'valid', null, 'data'];
const validInput = userInput.filter(Boolean); // ['valid','data']
高级用法:
// 链式调用
const result = data.filter(item => item.category === 'electronics').filter(item => item.price < 100).map(item => item.name);// 结合索引去重
const unique = array.filter((item, index) => array.indexOf(item) === index
);

9. find()

深度解析:
  • 技术原理:返回第一个使回调返回truthy的元素

  • 重要特性

    • 找到即停止遍历

    • 未找到返回undefined

    • filter()[0]更高效

使用场景: 
1.ID查找: 
const users = [/*...*/];
function findUser(id) {return users.find(user => user.id === id);
}
2.条件查找
const inventory = [{ name: 'apple', color: 'red' },{ name: 'banana', color: 'yellow' }
];const yellowFruit = inventory.find(f => f.color === 'yellow');
3.配置查找
const configOptions = [{ env: 'dev', apiUrl: 'dev.api.com' },{ env: 'prod', apiUrl: 'api.com' }
];const currentConfig = configOptions.find(c => c.env === process.env.NODE_ENV
);
findIndex配合:
const index = users.findIndex(user => user.id === 123);
if(index !== -1) {// 更新用户users[index] = updatedUser;
}

10. includes()

深度解析:
  • 技术原理:使用SameValueZero算法检查包含性

  • 关键特性

    • NaN可以匹配NaN

    • 区分+0和-0

    • 对象比较引用而非内容

使用场景: 
1.简单值存在检查
const validStatuses = ['active', 'pending', 'completed'];function isValidStatus(status) {return validStatuses.includes(status);
}
2.功能开关控制
const enabledFeatures = getUserFeatures();if(enabledFeatures.includes('dark_mode')) {enableDarkMode();
}
 3.白名单验证
const ALLOWED_FILE_TYPES = ['image/jpeg', 'image/png'];function isValidFile(file) {return ALLOWED_FILE_TYPES.includes(file.type);
}
对象数组处理:
// 无法直接查找对象
const items = [{id:1}, {id:2}];
console.log(items.includes({id:1})); // false// 解决方案:
const target = {id:1};
const itemSet = new Set(items.map(i => i.id));
console.log(itemSet.has(1)); // true// 或使用some
const exists = items.some(item => item.id === 1);

专业级总结:选择指南

场景推荐方法原因
遍历数组for...of 或 forEach简洁性 vs 可中断性
数据转换map纯函数,无副作用
数据筛选filter声明式编程
查找元素find / findIndex高效(短路特性)
存在检查includes (简单值) / some (复杂)语义化清晰
添加元素push (尾) / unshift (头,慎用)性能考虑
移除元素pop (尾) / shift (头,慎用)性能考虑
清空数组arr.length = 0最高性能
异步遍历for...of + await顺序执行
复杂数据操作reduce (未列出)灵活处理累积操作

高级建议

1.不可变性原则:优先使用mapfilterslice等非变异方法
2.性能敏感操作
// 大数组操作使用TypedArray
const buffer = new Float64Array(1000000);// 替代shift/unshift
class CircularBuffer {// 实现循环缓冲区
}
3.函数式编程组合
import { pipe } from 'lodash/fp';const processData = pipe(filter(validCondition),map(transform),sort(comparator)
);const result = processData(rawData);

http://www.xdnf.cn/news/1205353.html

相关文章:

  • ROS2入门之开发环境搭建
  • 【C++】手搓一个STL风格的vector容器
  • vue如何在data里使用this
  • 屏幕晃动机cad【4张】三维图+设计说明书
  • Java面试宝典:MySQL8新特性
  • 软工八将:软件开发全流程核心角色体系解析
  • kubectl中的yaml配置详解
  • 【Unity游戏】——1.俄罗斯方块
  • 【大模型LLM】梯度累积(Gradient Accumulation)原理详解
  • 软件设计师-知识点记录
  • creating and using sequence
  • AI论文阅读方法+arixiv
  • Redis未授权访问的利用的几种方法原理以及条件
  • yolo 目标检测600类目标
  • STM32中集成USB驱动
  • STM32 USB HOST 驱动FT232 USB转串
  • Android 解析 TrafficDescriptor 的 OSAPP 信息
  • OpenLayers 综合案例-区域掩膜
  • [机缘参悟-237]:AI人工神经网络与人类的神经网络工作原理的相似性
  • SpringBoot数学实例:高等数学实战
  • 7.项目起步(1)
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现面部口罩的检测识别(C#代码,UI界面版)
  • 数据结构(动态数组)
  • HTML应用指南:利用GET请求获取全国小米之家门店位置信息
  • 第4章唯一ID生成器——4.2 单调递增的唯一ID
  • 【Zustand】从复杂到简洁:Zustand 状态管理简化实战指南
  • 绿算技术携手昇腾发布高性能全闪硬盘缓存设备,推动AI大模型降本增效
  • Laravel 分页方案整理
  • 安宝特新闻丨Vuzix与Wyr.Ai合作推出基于M400眼镜的全新一代质检平台
  • springboot校园外卖配送系统