每个 Node 开发人员必须掌握的 10 个 JavaScript 概念

2025-05-28

每个 Node 开发人员必须掌握的 10 个 JavaScript 概念

Node.js凭借其在后端充分利用 JavaScript 的能力,迅速成为构建 Web 应用和系统软件的标准。Express 等热门框架Webpack等工具也助推了它的广泛应用。尽管存在DenoBun等竞争对手,但 Node 仍然是领先的服务器端 JavaScript 平台。

JavaScript 的多范式特性允许多种编程风格,但也带来了诸如作用域和对象变异之类的风险。缺乏尾调用优化使得大规模递归迭代非常危险,而 Node 的单线程架构需要异步代码来提高效率。尽管面临挑战,但遵循 JavaScript 中的关键概念和最佳实践可以帮助 Node.js 开发者编写可扩展且高效的代码。

1. JavaScript 闭包

JavaScript 中的闭包是指一个内部函数,即使外部函数返回控制权后,它仍然可以访问外部函数的作用域。闭包使内部函数的变量变为私有变量。函数式编程的流行度呈爆炸式增长,使得闭包成为 Node 开发者工具包中不可或缺的一部分。以下是 JavaScript 中闭包的一个简单示例:

图片描述

  • 变量 count 被赋值给一个外部函数。该外部函数只运行一次,将计数器设置为零并返回一个内部函数。_counter变量只能由内部函数访问,这使得它的行为类似于私有变量。
  • 这里的例子是一个高阶函数(或称元函数,即接受或返回另一个函数的函数)。闭包在许多其他应用中也很常见。当你在一个函数内部定义一个函数,并且内部函数既拥有自己的作用域,又能访问父函数的作用域时,就会发生闭包——也就是说,内部函数可以“看到”外部函数的变量,但反之则不行。
  • 这对于map(innerFunction)等函数方法也很方便,其中innerFunction可以使用外部范围内定义的变量。

2. JavaScript 原型

每个 JavaScript 函数都有一个原型属性,用于附加属性和方法。此属性不可枚举。它允许开发人员将方法或成员函数附加到其对象。JavaScript 仅通过原型属性支持继承。对于继承的对象,原型属性指向该对象的父对象。将方法附加到函数的一种常见方法是使用原型,如下所示:

图片描述

尽管现代 JavaScript 已经拥有相当完善的类支持,但它仍然在底层使用原型系统。这正是该语言灵活性的源泉。

3. 使用哈希名称定义私有属性

在过去,人们习惯在变量前加上下划线,以表明该变量是私有的。然而,这只是一个建议,而不是平台强制的限制。现代 JavaScript 为类提供了带 # 的私有成员和方法

图片描述

私有哈希名称是 JavaScript 中一个较新且非常受欢迎的功能!最新的 Node 版本和浏览器都支持它,Chrome 开发者工具也方便您直接访问私有变量。

4. 使用闭包定义私有属性

为了解决 JavaScript 原型系统中缺少私有属性的问题,你有时会看到另一种方法是使用闭包。现代 JavaScript 允许你使用 # 前缀来定义私有属性,如上例所示。然而,这在 JavaScript 原型系统中不起作用。此外,这也是你在代码中经常看到的一个技巧,理解它的作用非常重要。

使用闭包定义私有属性可以模拟私有变量。需要访问私有属性的成员函数应该在对象本身上定义。以下是使用闭包创建私有属性的语法:

图片描述

5. JavaScript 模块

曾几何时,JavaScript 没有模块系统,于是开发者们想出了一个巧妙的技巧(称为模块模式)来构建一个可以正常工作的模块系统。随着 JavaScript 的发展,它衍生出了不止一个,而是两个模块系统:CommonJS 的include语法和 ES6 的require语法。

Node 传统上使用的是 CommonJS,而浏览器使用的是 ES6。然而,最近几年的 Node 版本也支持 ES6。现在的趋势是使用 ES6 模块,希望有一天,所有 JavaScript 代码中都能使用同一种模块语法。ES6 如下所示(我们导出一个默认模块,然后导入它):

图片描述

您仍然会看到 CommonJS,并且有时需要使用它来导入模块。以下是使用 CommonJS 导出并导入默认模块的示例:

图片描述

6.错误处理

无论你使用哪种语言或环境,错误处理都至关重要且不可避免。Node 也不例外。处理错误的基本方式有三种:try/catch 代码块、抛出新的错误以及on()处理程序。

带有 try/catch 的块是出现问题时捕获错误的可靠方法:

图片描述

在这种情况下,我们使用console.error将错误记录到控制台。您可以选择抛出错误,并将其传递给下一个处理程序。请注意,这会中断代码流执行;也就是说,当前执行将停止,并由堆栈中上层的下一个错误处理程序接管:

图片描述

现代 JavaScript 在其Error对象上提供了许多实用的属性,包括用于查看堆栈跟踪的Error.stack 属性。在上面的示例中,我们通过构造函数参数设置了Error.message属性和Error.cause属性。

另一个容易发现错误的地方是异步代码块中,在这些代码块中,你可以使用.then()来处理正常结果。在这种情况下,你可以使用on('error')处理程序或onerror事件,具体取决于 Promise 返回错误的方式。有时,API 会将错误对象作为第二个返回值与正常值一起返回。(如果你在异步调用中使用 await ,则可以将其包装在 try/catch 中以处理任何错误。)以下是一个处理异步错误的简单示例:

图片描述

无论如何,千万不要吞掉错误!我不会在这里展示这一点,因为有人可能会复制粘贴它。基本上,如果你捕获了一个错误,然后什么也不做,你的程序就会默默地继续运行,没有任何明显的错误迹象。逻辑会被破坏,你只能苦苦思索,直到找到一个没有任何内容的 catch 块。(注意,提供一个没有 catch 块的finally{}块会导致你的错误被吞掉。)

7. JavaScript 柯里化

柯里化是一种使函数更灵活的方法。使用柯里化函数,你可以传递函数所需的所有参数并获取结果;或者,你可以只传递一部分参数,并接收一个等待剩余参数的函数。以下是一个简单的柯里化示例:

图片描述

可以通过将每个参数逐个放入单独的括号中来直接调用原始的柯里化函数:

图片描述

这是一个有趣的技巧,它允许你创建函数工厂,其中外部函数允许你部分配置内部函数。例如,你也可以像这样使用上面的柯里化函数:

图片描述

在实际使用中,当您需要创建许多根据特定参数而变化的函数时,这个想法会有所帮助。

8. JavaScript 应用、调用和绑定方法

虽然我们并非每天都会用到它们,但了解callapplybind方法的含义还是很有好处的。这里我们讨论的是语言的灵活性。本质上,这些方法允许你指定this关键字的解析结果。

在这三个函数中,第一个参数始终是您想要赋予函数的this值或上下文。

在这三种方法中,call是最简单的。它和在指定上下文的情况下调用一个函数是一样的。以下是一个例子:

图片描述

请注意,apply与call几乎相同。唯一的区别在于,您将参数作为数组传递,而不是单独传递。数组在 JavaScript 中更易于操作,为函数的使用提供了更多可能性。以下是使用applycall 的示例:

图片描述

bind方法允许你将参数传递给函数而无需调用它。它会返回一个新函数,其参数在任何其他参数之前被绑定。以下是示例:

图片描述

9. JavaScript 记忆

记忆化是一种优化技术,它通过存储开销较大的操作的结果,并在再次出现同一组输入时返回缓存的结果来加快函数执行速度。JavaScript 对象的行为类似于关联数组,这使得在 JavaScript 中实现记忆化变得非常简单。以下是如何将递归阶乘函数转换为记忆化阶乘函数:

图片描述

10. JavaScript IIFE

立即执行函数表达式 (IIFE) 是指创建后立即执行的函数。它与任何事件或异步执行无关。您可以像下面这样定义 IIFE:

图片描述

第一对括号function(){...}将括号内的代码转换为表达式。第二对括号调用表达式的结果函数。IIFE 也可以被描述为自调用的匿名函数。它最常见的用途是限制通过var创建的变量的作用域,或封装上下文以避免名称冲突。

还有一些情况需要使用await调用函数,但你不在异步函数块中。这种情况有时会发生在你希望直接执行并作为模块导入的文件中。你可以将这样的函数调用包装在 IIFE 块中,如下所示:

图片描述

11. 有用的论证特征

虽然 JavaScript 不支持方法重载(因为它可以处理函数中任意数量的参数),但它确实提供了一些强大的功能来处理参数。例如,你可以定义一个带有默认值的函数或方法:

图片描述

您还可以一次接受并处理所有参数,以便可以处理传入的任意数量的参数。这使用rest运算符将所有参数收集到一个数组中:

图片描述

如果您确实需要处理不同的参数配置,您可以随时检查它们:

图片描述

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

结论

随着你对 Node 的熟悉,你会发现几乎所有问题都有多种解决方法。正确的方法并不总是显而易见的。有时,对于某种情况,会有几种有效的方法。了解这些可用的选项会很有帮助。

这里讨论的 10 个 JavaScript 概念是每个 Node 开发者都应该了解的基础知识,但它们只是冰山一角。JavaScript 是一门强大而复杂的语言。你用得越多,就越能理解 JavaScript 的真正庞大,以及它能为你带来多少功能。

文章来源:https://dev.to/usman_awan/10-javascript-concepts-every-node-developer-must-master-2na
PREV
Git 备忘单
NEXT
Javascript:将嵌套 JSON 转换为简单 JSON 💎 很高兴看到您的回复