Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >这个库让JavaScript变“懒”了,但性能飞升啦

这个库让JavaScript变“懒”了,但性能飞升啦

作者头像
程序员老鱼
发布于 2023-09-07 00:55:18
发布于 2023-09-07 00:55:18
25700
代码可运行
举报
文章被收录于专栏:前端实验室前端实验室
运行总次数:0
代码可运行

在前端开发过程中,为了提高开发效率,我们会经常使用到第三方工具库。

尤其是在一些业务比较复杂的场景,原生 JavaScript 实现可能很啰嗦,但使用第三方工具库,通常一行代码就搞定了。

之前我们介绍过Underscore、Lodash、Ramda 多个第三方库工具库。今天,再给大家分享一个类似但非常独特的库:Lazy.js

简介

Lazy.js是类似Underscore或Lo-Dash的JavaScript工具库,但是它有一个非常独特的特性:惰性求值

很多情况下,惰性求值都将带来巨大的性能提升,特别是当处理巨大的数组和连锁使用多个方法的时候。Lazy.js的网站上展示了与Underscore、Lo-Dash比较的图表:

当数组非常大的时候,对于不需要迭代整个数组的方法,例如indexOf和take,Lazy.js的性能提升更为惊人:

安装

Lazy.js没有外部依赖,所以加载Lazy.js非常方便:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<script type="text/javascript" src="lazy.min.js"></script>

如果你希望支持DOM事件序列的惰性求值,那么用这个:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<script type="text/javascript" src="lazy.dom.js"></script>

如果你使用Node.js:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npm install lazy.js

性能对比

让我们创建一个包含1000个整数的数组:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var array = Lazy.range(1000).toArray();

注意我们调用了toArray。如果没有这个,Lazy.range给我们的将不是一个数组而是一个Lazy.Sequence对象,你可以通过each来迭代这个对象。

现在我们打算取每个数字的平方,再加一,最后取出前5个偶数。为了保持代码简短,我们使用这些辅助函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function square(x) { return x * x; }
function inc(x) { return x + 1; }
function isEven(x) { return x % 2 === 0; }

我们可以使用Underscore的chain方法实现它:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var result = _.chain(array).map(square).map(inc).filter(isEven).take(5).value();

注意,上面这行语句做了如下事情:

  • map(square)迭代了整个数组,创建了一个新的包含1000个元素的数组
  • map(inc)迭代了新的数组,创建了另一个新的包含1000个元素的数组
  • filter(isEven)迭代了整个数组,创建了一个包含500个元素的新数组
  • take(5)这一切只是为了5个元素!

如果你需要考虑性能,你可能不会这么干。因为,它生成了中间数组,且这些中间数组仅仅是为了最后的5个数,后续再无用处。

相反,你会写出类似这样的过程式代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var results = [];
for (var i = 0; i < array.length; ++i) {
  var value = (array[i] * array[i]) + 1;
  if (value % 2 === 0) {
    results.push(value);
    if (results.length === 5) {
      break;
    }
  }
}

现在我们没有创建任何多余的数组,在一次迭代中完成了一切。貌似很好。但也有问题。

最大的问题在于:这是一次性的代码,我们花了一点时间编写了这段代码,却无法复用。

要是我们能够利用Underscore的表达力,同时得到手写的过程式代码的性能,那该多好啊!

这就是懒惰.js的用武之地!以下是我们使用 Lazy.js 编写上述代码的方式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var result = Lazy(array).map(square).map(inc).filter(isEven).take(5);

看上去和用Underscore的代码几乎一样?正是如此:Lazy.js希望带给JavaScript开发者熟悉的体验。每个Underscore的方法应该和Lazy.js有相同的名字和表现,唯一的不同是Lazy.js返回一个序列对象,以及相应的each方法。

重要的是,直到你调用了each才会产生迭代,而且不会创建中间数组。

Lazy.js将所有查询操作组合成一个序列,最终的表现和我们开始写的过程式代码差不多。

但与过程式代码不同的是:Lazy.js确保你的代码是干净的,函数式的。 这样你就可以专注于构建应用,而不是优化遍历数组的代码。

本质上,Lazy.js将所有查询操作组合成一个“序列”,其行为与我们刚才编写的过程代码非常相似。(如果你确实想要一个数组,只需将结果序列出来)

其他

除了性能上优越外,Lazy.js 还有其他特性,诸如生成无穷序列,异步迭代,处理Dom事件(小扩展lazy.dom.js),字符串处理,流处理等功能。

详细的使用,请大家参阅下方链接。

官方地址 https://danieltao.com/lazy.js/ Github地址 https://github.com/dtao/lazy.js/

注意官网首页最后一句话:This library is experimental and still a work in progress. Lazy.js是试验性的,仍在开发中。

因此,在正式环境中,大家酌情使用哦~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
✨从延迟处理讲起,JavaScript 也能惰性编程?
我们从闭包起源开始、再到百变柯里化等一票高阶函数,再讲到纯函数、纯函数的组合以及简化演算;
掘金安东尼
2022/10/28
7120
✨从延迟处理讲起,JavaScript 也能惰性编程?
惰性求值——lodash源码解读
lodash受欢迎的一个原因,是其优异的计算性能。而其性能能有这么突出的表现,很大部分就来源于其使用的算法——惰性求值。 本文将讲述lodash源码中,惰性求值的原理和实现。
我是leon
2019/08/28
1.5K0
惰性求值——lodash源码解读
《The Joy of Javascript》- 5 - Data
需要注意的是 for await……of 需要一个对象拥有一个 function-valued symbol property Symbol.asyncIterator, 因此可以如此设计一个对象用于 for await……of
szhshp
2022/09/21
6940
immutable.js 简介
Immutable数据就是一旦创建,就不能更改的数据。每当对Immutable对象进行修改的时候,就会返回一个新的Immutable对象,以此来保证数据的不可变
江米小枣
2020/06/16
1.6K0
immutable.js 简介
最全面的前端开发指南
HTML 语义 HTML5为我们提供了很多旨在精确描述内容的语义元素。确保你可以从它丰富的词汇中获益。 <!-- bad --> <div id="main"> <div class="article"> <div class="header"> <h1>Blog post</h1> <p>Published: <span>21st Feb, 2015</span></p> </div> <p>…</p> </div> </div> <!-- go
前朝楚水
2018/04/02
7950
每个 JavaScript 程序员都应该掌握这个工具!
大师兄最近对一个工具库的使用上瘾了!这个给大家分享下。这是每个 JavaScript 程序员都应该掌握的工具:Ramda
程序员老鱼
2022/12/22
7900
每个 JavaScript 程序员都应该掌握这个工具!
70个JavaScript面试问题
它们是属于虚值,可以使用Boolean(value)或!!value将其转换为布尔值时,值为false。
前端迷
2020/02/19
1.5K0
70个JavaScript面试问题
如何用 JavaScript 实现一个数组惰性求值库
看到函数式语言里面的惰性求值,想自己用 JavaScript 写一个最简实现,加深对惰性求值了解。用了两种方法,都不到 80 行实现了基本的数组的惰性求值。
哲洛不闹
2018/09/14
8160
如何用 JavaScript 实现一个数组惰性求值库
熬夜7天,我总结了JavaScript与ES的25个重要知识点!
说起JavaScript,大家都知道是一门脚本语言。那么ES是什么鬼呢?ES全称ECMAScript ,是JavaScript语言的国际标准。
达达前端
2020/09/17
1.8K0
熬夜7天,我总结了JavaScript与ES的25个重要知识点!
javascript常用技巧
map() (映射)方法最后生成一个新数组,不改变原始数组的值。其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
前端_AWhile
2019/09/16
7850
JavaScript对象length
前几日有在Javascript数组操作一文中稍提及了数组的length属性;深入一点探究,就发现JS这length确有许多难为所知的特性。这就边学边探究下这朵奇葩属性;这里边深入边记载。 可变的数组length属性 和其他大多数语言不同的是,JavaScript数组的length属性是可变的,这一点需要特别注意。当length属性被设置得更大时,整个数组的状态事实上不会发生变化,仅仅是length属性变大;当length属性被设置得比原来小时,则原先数组中索引大于或等于length的元素的值全部被丢失。下面
晚晴幽草轩轩主
2018/03/27
2.6K0
React极简教程: Hello,World!React简史React安装Hello,World
A programming paradigm is a fundamental style of computer programming. There are four main paradigms: imperative, declarative, functional (which is considered a subset of the declarative paradigm) and object-oriented. Declarative programming : is a programming paradigm that expresses the logic of a computation(What do) without describing its control flow(How do). Some well-known examples of declarative domain specific languages (DSLs) include CSS, regular expressions, and a subset of SQL (SELECT queries, for example) Many markup languages such as HTML, MXML, XAML, XSLT… are often declarative. The declarative programming try to blur the distinction between a program as a set of instructions and a program as an assertion about the desired answer. Imperative programming : is a programming paradigm that describes computation in terms of statements that change a program state. The declarative programs can be dually viewed as programming commands or mathematical assertions. Functional programming : is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions, in contrast to the imperative programming style, which emphasizes changes in state. In a pure functional language, such as Haskell, all functions are without side effects, and state changes are only represented as functions that transform the state. ( 出处:维基百科)
一个会写诗的程序员
2018/08/20
6440
你不知道的高性能JAVASCRIPT | TW洞见
想必大家都知道,JavaScrip是全栈开发语言,浏览器,手机,服务器端都可以看到JS的身影。 本文会分享一些高效的JavaScript的最佳实践,提高大家对JS的底层和实现原理的理解。 数据存储 计算机学科中有一个经典问题是通过改变数据存储的位置来获得最佳的读写性能,在JavaScript中,数据存储的位置会对代码性能产生重大影响。 - 能使用{}创建对象就不要使用new Object,能使用[]创建数组就不要使用new Array。JS中字面量的访问速度要高于对象。 - 变量在作用域链中的位置越深,访
ThoughtWorks
2018/04/17
8370
JavaScript高级程序设计-性能整理(一)
当然,在把 HTMLElement 元素添加到 DOM 且执行到这段代码之前不会发送请求。默认情况下,以这种方式创建的<script>元素是以异步方式加载的,相当于添加了 async 属性。不过这样做可能会 有问题,因为所有浏览器都支持 createElement()方法,但不是所有浏览器都支持 async 属性。因此,如果要统一动态脚本的加载行为,可以明确将其设置为同步加载:
草帽lufei
2022/07/29
7310
JavaScript性能提升学习
不支持defer属性的浏览器:defer、script、load 支持defer属性的浏览器:script、defer、load 3.2 动态添加script标签,添加到head中比添加到body中安全 3.3 XHR动态脚本注入兼容性好,但不能跨域
csxiaoyao
2019/02/15
1.4K0
前端性能优化之 JavaScript
本文为 《JavaScript》 读书笔记,是利用中午休息时间、下班时间以及周末整理出来的,此书虽有点老旧,但谈论的性能优化话题是每位同学必须理解和掌握的,业务响应速度直接影响用户体验。
Jack Chen
2019/06/18
1.9K0
推荐 5 个 JavaScript 字符串插件库
英文 | https://blog.bitsrc.io/5-string-manipulation-libraries-for-javascript-9ca5da8b4eb8
前端达人
2021/10/25
1.1K0
推荐 5 个 JavaScript 字符串插件库
学习 lodash 源码整体架构,打造属于自己的函数式编程类库
这是 学习源码整体架构系列第三篇。整体架构这词语好像有点大,姑且就算是源码整体结构吧,主要就是学习是代码整体结构,不深究其他不是主线的具体函数的实现。文章学习的是打包整合后的代码,不是实际仓库中的拆分的代码。
ConardLi
2019/09/17
2.3K0
学习 lodash 源码整体架构,打造属于自己的函数式编程类库
JavaScript基础
脚本语言,语法类似于java(脚本语言又被称为扩建的语言,或者动态语言,是一种编程语言,用来控制软件应用程序,脚本通常以文本(如ASCII)保存,只在被调用时进行解释或编译。)
xiaozhangStu
2023/05/04
4020
如何使用GPU改善JavaScript性能
作为开发者,我们总是寻找机会来提高应用程序的性能。当涉及到网络应用时,我们主要在代码中进行这些改进。
徐小夕
2021/07/12
2K0
相关推荐
✨从延迟处理讲起,JavaScript 也能惰性编程?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验