继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

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

蝴蝶不菲
关注TA
已关注
手记 388
粉丝 81
获赞 381

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的广阔天地和你能用它做到的事情。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP