Nodejs开发进阶9-REPL

本章节,我们来讨论一下nodejs中的REPL,一个对学习和开发非常有帮助的工具。

概述

从广泛的定义而言,REPL(Read读取, Evaluate评估, Print打印, Loop循环)是一种实时的程序开发、探究、评估和使用模式和环境。

nodejs内置提供了REPL的实现,特别是它的使用非常方便。我们知道,在操作系统命令行环境中,通过输入"node"命令可以执行node程序,如果把js文件名作为参数,就可以让nodejs执行这个js文件(输入".",可以执行当前目录中的index.js文件作为默认文件);而如果不带任何参数,就会进入nodejs的REPL环境:

kotlin 复制代码
yanjh@WK-YANJH-AMD:~$ node
Welcome to Node.js v14.16.0.
Type ".help" for more information.
> .help
.break    Sometimes you get stuck, this gets you out
.clear    Alias for .break
.editor   Enter editor mode
.exit     Exit the REPL
.help     Print this help message
.load     Load JS from a file into the REPL session
.save     Save all evaluated commands in this REPL session to a file

Press Ctrl+C to abort current expression, Ctrl+D to exit the REPL

这是一个交互式环境,类似操作系统的命令行环境,就是用户输入命令或者代码,就可以立刻执行。为了和操作系统环境分开,这里使用提示符">"。

这里我们输入.help,就可以查看帮助信息,这里就是可用的命令。因为REPL也可以执行和输入代码,所以使用点号前缀的表示这是一个REPL指令,和普通的js代码是区分开来的。比如我们再输入.exit,就可以退出REPL环境,回到操作系统命令行。当然,如果我们输入js代码,将会执行相应的js程序。

应用场景

大概并体验了解了REPL是什么之后,我们来思考一下这个东西设计的目的和应用的场景是什么。其实非常简单:

方便,高效

使用REPL非常方便,不需要编辑器,不需要执行器,不需要打开、编辑、保存文件,也不需要启动、执行命令,直接的编写和执行代码,正确或者错误立刻知晓。而且这个过程轻量,轻松,愉快。这些特性和体验,在开发者整个的构思-编码-验证的工作链条和循环中,可以提供极高的效率。所以,笔者建议开发者积极尝试REPL的使用,找到自己适合的方式,这些方式可能包括:

  • 学习js语法

哪怕是对有经验的开发者而言,也不可能熟悉和掌握所有的js语法、对象特性和方法,就需要一种高效的查阅和验证机制。当然查询技术文档也是一个方法,但毕竟所有的代码都必须能够在真实环境中运行,RPEL就提供了这一一个很好的PlayGround,来帮助开发者方便快速的熟悉这些特性。显然,这个特性,对于初学者就更加方便有效了就像儿童的游乐场一样,可以先不在正式的环境中操作代码,也可以来熟悉这些语法和功能。

  • 快速代码和方法验证

REPL适合来验证单一的代码片段和逻辑,不太适合于太复杂和冗长的代码。恰好,js语言的简洁高效也适合于这个特点。后面我们有实例可以看到这一点。

  • 语法提示

在使用REPL环境编写代码时,对于一些方法和类,REPL可以根据上下文进行语法的提示补全,让开发者可以快速的了解相关的对象特性和语法。

  • 查看类定义

很多开发者可能没有注意到,在REPL中,可以快速的查看类定义,省去了很多查阅技术文档的时间。比如:

js 复制代码
> console
Object [console] {
  log: [Function: log],
  warn: [Function: warn],
  dir: [Function: dir],
  time: [Function: time],
  timeEnd: [Function: timeEnd],
  timeLog: [Function: timeLog],
  trace: [Function: trace],
  assert: [Function: assert],
  clear: [Function: clear],
  count: [Function: count],
  countReset: [Function: countReset],
  group: [Function: group],
  groupEnd: [Function: groupEnd],
  table: [Function: table],
  debug: [Function: debug],
  info: [Function: info],
  dirxml: [Function: dirxml],
  error: [Function: error],
  groupCollapsed: [Function: groupCollapsed],
  Console: [Function: Console],
  profile: [Function: profile],
  profileEnd: [Function: profileEnd],
  timeStamp: [Function: timeStamp],
  context: [Function: context]
}

在理解了这些使用场景后,我们来看看它是如何工作的。

工作流程

它的工作原理和流程,就是那四个字母: R-E-P-L。

  • Read(读取)

和普通的命令行交互环境不同。用户可以直接在REPL内输入代码。代码输入完成后,可以使用回车结束这一轮的代码输入,REPL程序就会进入下一个执行阶段-求值。

如果我们输入的代码不是一行的,可以使用ctrl+c另起一行,这时代码会换行显示,但不会真正的执行。也可以使用.editor命令,进入编辑器模式,这时候的换行就是文本换行,而非开始执行命令(ctrl+d结束编辑并执行)。

  • Evaluate(求值)

这里的求值,其实就是加载和运行读取阶段得代码。REPL的执行命令分隔符是"回车"。也就是说,当你输入回车的时候,求值过程就开始启动和执行。

有些代码是可以有计算结果的,这时会有一个结果值。但有些代码可能只是一些操作,比如赋值,它并没有明确的返回值。这时REPL会认为它的结果是undefined。

  • Print(打印)

打印,就是输出处理结果了。需要注意,REPL永远都输出在一次循环中的最后的那个计算结果。而且REPL的操作是实时的,它会在你输入的时候,就试图输出计算的结果,提供了很好的体验。前面提到,如果最后的步骤不是一个计算,比如是一个赋值,它也会输出一个"undefined",可能是因为这个操作没有返回一个明确可定义的结果吧。

  • Loop (循环)

这个在说明,REPL是一个交互循环的过程,在一个流程结束后,就可以进入下一个流程,无需其他操作,可以一直进行下去。REPL还有session的概念,虽然有很多loop,但它们还是在一个运行环境中的,就是那些赋值和定义,都还有效,在后面也可以使用。如果我们要清除这个环境,也可以使用.clear命令。

这几个步骤和流程看起来复杂,其实真正操作起来是很简单的,就是输入命令和指令,就可以执行查看结果,和操作系统的命令行接口的逻辑,是一样的。还是建议读者实际操作体验,可以更直观深入的理解这一点。

实操

这里笔者例举了一些REPL操作的实例,希望可以帮助读者更好的理解它的应用:

js 复制代码
// 1 理解Buffer和base64编码
> Buffer.from("China中国")
<Buffer 43 68 69 6e 61 e4 b8 ad e5 9b bd>
> Buffer.from("China中国").toString("base64")
'Q2hpbmHkuK3lm70=

// 2 理解Array的数据类型
> typeof []
'object'
> typeof ""
'string'
> Array.isArray("");

// 3 crypto sha1Hmac
> crypto.createHmac("SHA1","somekey").update("content").digest("hex")
'f0e59fee8f991dc67274c51f231e416d6ab79627'

// 4 Reduce用法测试
> Buffer.from("what's up").reduce((c,v,i)=>c+v,0)
851
> Buffer.from("what's up").reduce((c,v,i)=>c+v.toString(10).padStart("0",3),"")
'119104971163911532117112'

// 5 js解构方法学习

> let {id,name} = {id: "1234", name:"John Yan"}
undefined
> id
'1234'
> name
'John Yan'

// 6 ID卡编码转换
> parseInt(parseInt(0616988734).toString(16).match(/.{2}/g).reverse().join(""),16).toString().slice(-10);
'1048626724'

几个要点和有趣的地方:

  • js的链式语法操作,特别适合于编写快速验证代码
  • REPL并不非常严格遵循JS语法,比如可以直接声明和变量
  • 很多全局变量、库和方法,在REPL中是可以直接使用的,如crypto
  • 规划良好的话,console不是必须的,REPL会输出结果和内容,但如果考虑明确或多个内容的话,也可以使用console
  • 如果要运行一个已存在的js代码块,可以使用.load指令
  • 一些实验性代码需要保存的话,可以使用.save指令记录当前的状态和设置
  • 迄今为止,笔者尚未遇到需要.break的场合,所以这部分内容不知如何阐述

IDE中的REPL

REPL并非nodejs独有的概念或者技术,比如很多IDE环境中,就集成或者可以安装REPL,来方便开发者的工作。在笔者使用的VSCode这个集成开发环境中,就可以通过插件的方式,来安装使用REPL。

可以在VSCode插件面板中搜索REPL,就可以看到Node.js REPL这个插件,安装完成后,可以通过快捷键Ctrl+Shift+P启动插件程序菜单,搜索并启动REPL就可以开始使用了。

这个命令会启动一个编辑器来操作REPL(下图),可以看到,比node的REPL更方便的是,它同时可以保存和显示多个命令代码状态,更方便代码验证和设计。

小结

本文讨论了何为REPL,包括基本概念、工作原理和流程,以及它如何帮助开发者进行编程语言的学习和开发的辅助工作。并通过一些简单的示例,来说明其实际使用方式和特点。

相关推荐
林的快手6 分钟前
CSS列表属性
前端·javascript·css·ajax·firefox·html5·safari
程序员侠客行23 分钟前
Spring事务原理 二
java·后端·spring
匹马夕阳32 分钟前
ECharts极简入门
前端·信息可视化·echarts
bug总结37 分钟前
新学一个JavaScript 的 classList API
开发语言·javascript·ecmascript
网络安全-老纪1 小时前
网络安全-js安全知识点与XSS常用payloads
javascript·安全·web安全
API_technology1 小时前
电商API安全防护:JWT令牌与XSS防御实战
前端·安全·xss
sjsjsbbsbsn1 小时前
Spring Boot定时任务原理
java·spring boot·后端
yqcoder1 小时前
Express + MongoDB 实现在筛选时间段中用户名的模糊查询
java·前端·javascript
十八朵郁金香1 小时前
通俗易懂的DOM1级标准介绍
开发语言·前端·javascript
计算机毕设指导62 小时前
基于Springboot学生宿舍水电信息管理系统【附源码】
java·spring boot·后端·mysql·spring·tomcat·maven