为了账号安全,请及时绑定邮箱和手机立即绑定

10 JavaScript 概念们或每个使用 Node 的开发者必须掌握的 JavaScript 概念

标签:
JavaScript

Node.js 快速成为构建 Web 应用和系统软件的标准,得益于它能够在后端使用 JavaScript。流行框架如 Express 和工具如 Webpack 等也促成了它的广泛应用。尽管存在诸如 DenoBun 等竞争对手,Node 仍然是领先的服务器端 JavaScript 平台之一。

JavaScript的多范式特性允许使用各种编程风格,但也带来了诸如作用域和对象变更的风险。缺乏尾递归优化使得大的递归操作变得危险,并且Node.js的单线程特性需要使用异步代码来保持高效。尽管存在这些难题,遵循JavaScript的关键理念和最佳实践可以帮助Node.js开发人员写出可扩展且高效的代码。

zh: 1. JavaScript 闭包: 一个闭包是指一个函数与其声明时所在的词法环境的组合。

在JavaScript中,闭包是一个内部函数,即使外部函数已经返回,仍然可以访问外部函数的作用域。闭包使内部函数的变量保持私有。随着函数式编程的流行,闭包已经成为Node开发者工具箱中不可或缺的一部分。这里有一个简单的JavaScript闭包示例。

这是一张图片,你可以点击链接查看。图片描述

  • 变量count被赋值给一个外部函数。外部函数仅运行一次,将计数器设置为零并返回一个内部函数。变量_counter只能由内部函数访问,这使它表现得像一个私有的变量。
  • 这里的例子是一个高阶函数(或元函数,即接受或返回另一个函数的函数)。闭包在许多其他应用场景中也可以找到。当在另一个函数内部定义一个函数时,并且该内部函数不仅拥有自己的作用域,还可以访问父作用域,就会发生闭包。也就是说,内部函数可以“访问”外部变量,而外部函数则不能访问内部函数的作用域。
  • 在使用诸如map(innerFunction)这样的函数方法时,这也非常有用,因为innerFunction可以使用在外部作用域中定义的变量。

2. JavaScript原型系统

每个 JavaScript 函数都有一个 prototype 属性,用于附加属性和方法到函数上。此属性是不可枚举的。它允许开发人员向其对象附加方法或成员函数。JavaScript 的继承只能通过 prototype 属性来实现。当对象继承自其他对象时,prototype 属性指向该对象的原型对象。通常会通过原型来添加方法到函数,如下所示:

这是一张图片:图片描述

尽管现代 JavaScript 已经具备相当复杂的类支持,它仍然在底层使用原型系统。这正是该语言灵活性的一个重要原因。

3. 使用哈希名称设定私有特性

在过去,用下划线开头的变量表示该变量是私有的。然而,这只是个建议性做法,并不是平台强制要求的限制。现代 JavaScript 提供了 # 私有成员和方法

图片描述 这是一张图片

私有属性名是 JavaScript 中一个较新且非常棒的新功能!最近的 Node.js 版本和大多数浏览器都已经支持这一功能,Chrome 的开发者工具还让你可以直接访问私有变量,方便得很。

4. 使用闭包来定义私有变量

另一种常见的方式是使用闭包来绕过JavaScript原型系统中缺乏私有成员的问题。现代JavaScript使用井号前缀来定义私有成员,如上例所示。但是,这种方法不适用于JavaScript原型系统中的私有成员定义。此外,这种技巧你经常会看到,理解它的工作原理是很重要的。

使用闭包定义私有属性可以让你模拟私有变量的效果。需要访问这些私有属性的成员函数应该直接定义在对象上。这里是使用闭包定义私有属性的语法:

看这张图片

zh: 5、JavaScript模块

很久以前,JavaScript 没有模块系统,开发人员设计了一个聪明的小技巧(称为模块模式)来搭建一个能用的系统。随着 JavaScript 的不断发展,它催生了不止一个,而是两个模块系统:CommonJS 的 include 用法和 ES6 require 语法。

节点(Node)传统上使用 CommonJS,而浏览器传统上使用的是另一种模块化方式(如 AMD 或者直接使用原生 ES6 模块,但在文本中没有明确说明,这里保持原翻译)。然而,最近的 Node 版本(例如,版本 10 及以上)也开始支持 ES6。现在大伙儿都开始倾向于使用 ES6 模块了,并且未来我们可能会在 JavaScript 中统一使用一种模块语法。ES6 的写法大致如下(例如,导出一个默认模块并进行导入):

图片描述 (点击可以查看。)

你仍然会看到CommonJS,并且有时需要使用它来导入模块。CommonJS中的具体操作如下:如何导出和导入默认模块。因此,这里展示了使用CommonJS导出和导入默认模块的方法。

图片描述

zh:6. 错误管理.

无论你处在什么样的语言环境,错误处理都是必要的。Node也一样。你会用到三种基本的方式来处理错误:try/catch结构、抛出新的异常以及on()事件处理器。

使用 try/catch 结构的代码块是用来捕捉错误的可靠方法,当出错时。

如图所示:图片描述
图片描述

在这种情况下,我们会把错误用 console.error 记录到控制台。你可以选择抛出错误,让下一个处理程序接手。需要注意的是,这样做会中断代码执行流程;也就是说,当前执行会停止,然后栈中的下一个错误处理程序会接手。

图片描述

现代 JavaScript 提供了多个有用的 Error 对象属性,比如可以用 Error.stack 来查看堆栈跟踪。在上面的例子中,我们用构造函数的参数设置了 Error.message

你还会在异步代码块中遇到错误,特别是在处理正常结果时使用 .then()。在这种情况下,你可以使用 on('error') 处理程序或 onerror 事件,具体取决于 promise 如何传递错误信息。有时,API 会将错误对象作为第二个返回值返回,而正常值作为第一个返回值。(如果你在异步调用中使用 await,可以用 try/catch 包裹来捕获并处理任何错误。) 这是一个简单的异步错误处理示例:

图片描述

不管怎样,千万别吞了错误!这里不展示,避免有人直接复制粘贴。总之,如果捕获了错误但没采取任何行动,你的程序会继续运行,毫无迹象显示出了问题。逻辑会出问题,你得琢磨为什么捕获块空着。(提示:只有finally{}块没有catch块,会导致错误被吞下。)

7. JavaScript 柯里化

柯里化是一种使函数更加灵活的方法。使用柯里化的函数,您可以传递所有期望的参数并得到结果,或者只传递部分参数,这样会返回一个等待其余参数的函数。下面是一个简单的柯里化示例:

图片描述

原始的 curried 函数可以直接这样调用:每个参数用一组单独的括号括起来依次调用。

例如:“curriedFunction(a)(b)(c)”

图片描述

这是一个有趣的技术,允许你创建函数生成器,在这种生成器中,外部函数可以部分地定制内部函数。比如,你可以这样使用上面提到的柯里化函数,比如:

- original code remains unchanged

图片描述

在实际应用中,这个概念或思路当你需要创建许多随某些参数变化的功能时,会对你有所帮助。

8. JavaScript 的 apply、call 和 bind 方法

虽然我们不是每天都用到它们,但了解一下 callapplybind 方法是什么还是不错的。这里我们讨论的是语言的一些灵活性。说到底,这些方法让你可以指定 this 关键字指向哪个对象。

在这三个函数中,第一个参数始终是你希望传递给函数的 this 值或上下文环境。

在这三个中,打电话是最简单的。就像在特定环境下调用一个函数一样。举个例子,

显示图片

注意 applycall 几乎相同。唯一的区别在于,您需要将参数作为数组传递,而不是分别传递。在JavaScript中,数组更容易操作,这为处理函数提供了更多的可能性。下面是一个使用 applycall 的示例:

图片描述,这是一张图片,你可以点击它查看详细内容。

bind 方法允许你向函数传递参数而无需调用它。返回一个新的函数,这些参数会被预先绑定,再接受其他的参数。例如:

图片

9. JavaScript 缓存

记忆化是一种优化技术,通过存储昂贵操作的返回值来加速函数执行,并当相同的输入再次出现时返回缓存的结果。JavaScript对象的行为类似于关联数组,使在JavaScript中实现记忆化变得简单。这里是如何将一个递归阶乘函数转换为记忆化版的阶乘函数的方法:

这张图片展示的是...图片

10. JavaScript 立即执行函数(IIFE)

立即执行的函数表达式(IIFE)是一种在创建时立即执行的函数。它与特定事件或异步任务无关。你可以这样定义一个IIFE:

如图所示:这是一张图片

第一个括号对 function(){...} 会将括号内的代码封装为一个表达式。第二个括号对会调用该内部创建的函数。IIFE(立即执行函数表达式,也称自调用匿名函数)可被描述为一个立即执行的匿名函数。它的最常见用途是通过 var 关键字限制变量的作用范围,或封装上下文以避免变量命名冲突。

有时你也会遇到这种情况,需要调用带有 await 的函数,但你没有在一个异步函数内部。这种情况通常发生在你希望它可以直接执行的文件中,同时也可能被当作模块导入的文件中。可以将这样的函数调用包裹在一个立即执行函数表达式(IIFE)中,例如:

图片描述 查看图片

11.: 有用的论据特点

尽管JavaScript不支持函数重载(因为它可以处理任意数量的函数参数),但它确实提供了几种强大的工具来处理参数。其中之一就是可以定义带有默认值的函数或方法:其中一个办法就是定义带有默认值的函数或方法。

图片描述 (点击查看图片)

您也可以一次性接受并处理所有参数,这种方法使用了rest操作符将其收集到一个数组中,以便处理任意数量的参数传递。

如图所示:图片

如果你确实需要处理不同参数配置的情况,你可以检查这些参数配置。

图片描述

另外,请记住JavaScript包含一个内置的arguments数组。每个函数或方法都会自动提供arguments变量,该变量包含了所有传递给该函数调用的参数。

zh: 结论

当你开始熟悉 Node 之后,你会注意到几乎每个问题都有很多解决方法。正确的方法有时候并不明显。有时候,面对某个问题可以有几种有效的解决方法。了解这些选择会对你有帮助。

这里提到的10个JavaScript概念每个Node.js开发者都应该知道,但这些概念只是冰山一角。JavaScript不仅强大,而且复杂。你用得越多,就越能理解JavaScript的广阔天地和你能用它做到的事情。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消