在Web前端开发中,如何优化前端数组处理方法? - Web前端
作者:98wpeu发布时间:2026-09-12分类:网页前端技术浏览:10
在Web前端开发中,如何优化前端数组处理方法?也许你已经遇到过讨论,我们是否应该使用Array方法(filter,map,reduce等)或循环(for,for...of,等)遍历集合。
关于数组的一些方法,我们分享过文章:
JS数组遍历之for循环方法应用解析
分享几种原生JS数组遍历的方法和应用
jquery数组封装使用方法分享(jquery数组遍历)
jquery进行数组遍历如何跳出当前的each循环
大家有兴趣的,可以去一一了解下。一段好的代码,会让你的程序性能更好且易理解,运行速度加快很多,相信大家都会知道这一点。
性能和可读性是选择一个而不是另一个的两个常见论点。让我们更好地看一下循环和array方法之间的差异并进行比较,以便我们自己决定。
性能
在ECMAScript 5之前,我们所拥有的只是循环和jQuery $.each。哪种迭代最快的方法经常引起争议。从那时起,情况有了很大的改善。从那时起,我们智能手机中的CPU的性能就超过了计算机,我们现在可以在客户端做更多很棒的工作,而不会崩溃整个浏览器。尽管如此,Array仍然提高了方法的性能。
tips: 如果要遍历大量项目,则可能要避免使用Array方法。
在大多数情况下,它不应有太大的区别。对于大多数项目,很少要遍历一百多个项目的列表。您通常可以使用您认为更易读的内容。只要确保始终检查低端设备的性能即可。
可读性
我们可以同意可读性很重要。这也是主观的。例如,让我们使用带有隐式return((a, b) => a + b)的箭头函数。初学者可能会将其与逻辑表达式混淆。大于或等于运算符(>=)看起来确实相似。也许他们可能没有意识到函数返回值。毕竟,返回是隐式的。训练有素的眼睛会立即注意到箭头的功能。对于所有其他语法也可以这样说。由我们决定培训初学者开发人员或不使用功能,以便任何技能水平的开发人员都可以访问代码库。话虽如此,让我们比较一些循环和Array方法的可读性。
Array.prototype.forEach而且for...of都易于阅读。
posts.foReach((post) => console.log(post));
// or
for (const post of posts) {
console.log(post);
}
等效的循环Array.PRototype.filter有点显式。
const drafts = posts.filter((post) => post.isDraft);
// or
const drafts = [];
for (const post of posts) {
if (post.isDraft) {
drafts.push(post);
}
}
也是一样Array.prototype.map。
const publishdates = post.map((post) => post.Date);
// or
const publishDates = new Array(posts.length);
for (let i = 0; i < posts.length; i++) {
publishDates[i] = posts[i].date;
}
Array.prototype.reduce确实很棒,但是可能要花几秒钟来了解正在发生的事情。即使对于类似求和的运算,您可能也需要一秒钟才能理解。当reduce回调包含更多逻辑时,可读性迅速变差。
const totalWordCount = posts
.reduce((result, post) => result + post.wordCount, 0);
// or
let totalWordCount = 0;
for (const post of posts) {
totalWordCount += post.wordCount;
}
对于其他方法,例如Array.prototype.every,,Array.prototype.find和Array.prototype.some,循环并不可怕,并且在具有早期返回功能的函数中效果更好。它们绝对比Array方法更明确。
const isEverythingPublished = posts.every((post) => post.isDraft);
// or
let isEverythingPublished = true;
for (const post of posts) {
if (post.isDraft) {
isEverythingPublished = false;
break;
}
}
// or in a function with early return
function getIsEverythingPublished(posts) {
for (const post of posts) {
if (post.isDraft) {
return false;
}
}
return true;
}
const isEverythingPublished = getIsEverythingPublished(posts);
如果您喜欢明确的话,循环可能会吸引您。对我来说,它们有点冗长,我个人更喜欢Array除之外的方法Array.prototype.reduce。但同样,可读性是主观的。这是私事。
特点与用途
尽管看起来循环和Array方法是做同一件事的两种方式,但是它们在显着方式上是不同的。
首先,Array方法是同步的。如果将异步函数传递给Array方法,它将不会等待异步函数完成。循环不依赖于回调,因此,如果您已经处于异步上下文中,则可以Await在循环块中或使用for await...of循环。
考虑下面的示例。这是一劳永逸的操作,传递给异步函数的Array.prototype.forEach调用被调用,但forEach不等待该函数完成。
const urls = [
'https://www.jiangweishan.com',
'https://www.web176.com',
];
urls.forEach(async () => {
const response = awAIt fetch(url);
if (!response.ok) {
console.warn(`Unable to Fetch ${url}`);
}
});
在下面的示例中,我们将异步函数传递给Array.prototype.map调用。因为一个异步函数总是返回Promise时,返回值map调用的列表promise。我们可传递给Promise.all,Promise.allSettled或Promise.race。这样,我们可以并行运行各种异步任务并等待结果。
Async function assertPageIsOk(url) {
const response = await fetch(url);
if (!response.ok) {
throw new error(`"GET ${url}" responded with ${response.statuscode}`);
}
return true;
}
const urls = [
'HTTPS://timseverien.com',
'https://timseverIEn.com/posts',
];
try {
await Promise.all(urls.map(assertPageIsOk));
} catch (error) {
console.error(error);
}
让我们使前面的示例稍微复杂一点。让我们依次调用每个URL,而不是同时触发所有请求(可能导致拒绝服务)。如果其中之一返回非2xx状态代码,我们可以停止序列。
function assertPagesAREOk(urls) {
return urls.reduce(async (chain, url) => {
await chain;
return assertPageIsOk(url);
}, Promise.resolve());
}
assertPagesAreOk(urls)
.then(() => ...)
.catch(() => ...);
这是上面的循环等效项:
async function assertPagesAreOk(urls) {
for (const url of urls) {
await assertPageIsOk(url);
}
return true;
}
assertPagesAreOk(urls)
.then(() => ...)
.catch(() => ...);
在以上所有示例中,我发现循环均等或更具可读性。
循环和Array方法之间的第二个重要区别是数组不能无限大。通常,我们认为无限循环是一件坏事,但它们可能非常有用。
想象一下,我们正在开发一个现代散点图库,该库中我们想在画布上绘制大量点。由于数组大小有限,因此我们可以通过允许用户传递生成器函数来利用迭代器。
import createScatterPlot from 'scatman';
createScatterPlot({
data: *function() {
while (true) {
yield {
x: Math.ranDOM(),
y: Math.random(),
};
}
},
});
生成器函数返回生成器对象,它是迭代器的超集。它们可以转换为数组(通过[...iterator]或Array.from(iterator)),也可以循环使用。如前所述,数组的最大大小是一个限制。另一方面,在循环中,当循环需要下一个值时,会将各个值从迭代器中拉出。因为我们在示例中生成了无限点,所以将其转换为数组将冻结浏览器。
for (const { x, y } of data) {
draw(x, y);
await waitForNextFrame();
}
总结
我们已经知道循环速度更快,但是Array当方法内部处理某些逻辑(例如创建新数组或滤除特定值)时,方法可以提高可读性。我们还看到,在处理异步任务时,循环更具可读性,并了解到循环对于迭代未知数量的项目很有用,这在迭代器中很常见。
在大多数情况下,我们将使用它们中的任何一个来遍历少于一千个项目的数组,在这种情况下,我们应该强烈倾向于更具可读性的选项。我觉得Array除以外的方法更具可读性Array.prototype.reduce。我经常看到前者在使用这种方法时遇到了麻烦,而没有完全了解它的行为。
无论如何,没有人比您更了解您,您的团队或您的项目。也许您是在一个全栈的团队中工作的,他们对循环比对Array方法更熟悉。也许这些Array方法更符合您的函数式编程原理。您(和您的团队)将不得不弄清楚这一点。
相关推荐
- Javascript:实现鼠标放到图片上后的放大镜效果 - Web前端
- 聊聊vue中的路由原理以及一些简单的应用 - Web前端
- 微软的TypeScript 4.0编程语言问世:这是一个重要的里程碑 - Web前端
- 提升和优化变量和函数的应用 - Web前端
- 为什么苹果的反托拉斯之争可能意味着iOS的终结 - Web前端
- 分享前端面试中面试官提到的Node.js一些问题与解决方案 - Web前端
- 入门前端框架的必备知识点:深度比较React和Angular - Web前端
- Microsoft对开发人员:告别基于云的开发环境Visual Studio Codespaces - Web前端
- 使用Vue 3.0 Composition API构建购物清单应用 - Web前端
- 分享按钮点击CSS3特效:酷炫发散效果 - Web前端
- 网页前端技术排行
-
- 1[Web前端]用javascript实现默认图片替代未显示的图片 - Web前端
- 2分析Iconfont-阿里巴巴矢量常用图标库 - Web前端
- 3jQuery实例教程:制作网页中可折叠的面板 - Web前端
- 4【第六章】Foundation之按钮和下拉功能 - Web前端
- 5基于jquery的滚动条滚动固定div(附演示下载) - Web前端
- 6jQuery编写widget的一些技巧分享 - Web前端
- 7分享精心挑选的12款优秀jQuery Ajax分页插件和教程 - Web前端
- 8jQuery实现鼠标移到元素上动态提示消息框效果 - Web前端
- 9在Mac/PC上远程调试iPhone/iPad上的网页 - Web前端
- 最近发表
-
- WordPress随机显示特色图片插件:Random Post Thumbnails
- KeePass实现Chrome浏览器自动填充密码方法一
- LNMP一键包nginx 301强制跳转到https教程
- KeePass实现Chrome浏览器自动填充密码方法二
- #建站# 免费的VPS管理软件Xshell8/Xftp8中文版下载
- 使用Xshell 8连接VPS教程_电脑登录vps的方法
- WordPress评论界面添加烟花????效果
- 不同浏览器书签同步方案:坚果云+Floccus_详细使用教程
- iOS端KeePassXC客户端APP:Strongbox Password Safe
- 给WordPress评论中的Gravatar头像图片添加ALT属性


