百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 博客教程 > 正文

前端开发人员必须掌握的10个JavaScript概念

connygpt 2024-12-08 14:21 9 浏览

Node.js迅速成为构建Web应用程序和系统软件的标准,这要归功于它能够在后端利用JavaScript。像 Express这样的流行框架和Webpack这样的工具有助于它的广泛使用。尽管像 Deno和Bun 这样的竞争对手存在,但Node仍然是领先的服务器端JavaScript 平台。

JavaScript的多范式特性允许使用各种编程风格,但也存在一些风险,如作用域和对象突变。缺乏tail-call优化使得大型递归迭代变得危险,而Node 的单线程架构需要异步代码来提高效率。尽管存在这些挑战,但在JavaScript中遵循关键概念和最佳实践可以帮助Node.js开发人员编写可扩展和高效的代码。

JavaScript闭包

在JavaScript 中,闭包是一个内部函数,它可以访问外部函数的作用域,即使外部函数已经返回控制。闭包使内部函数的变量私有化。函数式编程已经变得非常流行,使得闭包成为 Node 开发人员工具包的重要组成部分。这是 JavaScript 中闭包的一个简单示例:

  • 变量count被分配给了一个外层函数。外层函数只运行一次,它将计数器设置为零并返回一个内层函数。_counter 变量只能被内层函数访问,这使得它的行为类似于一个私有变量。
  • 这里的例子是一个高阶函数(或元函数,一个接受或返回另一个函数的函数)。闭包在许多其他应用程序中都有发现。只要在另一个函数内部定义一个函数,并且内部函数既具有自己的作用域,又可以访问父作用域,那么就会发生闭包 - 也就是说,内部函数可以“看到”外部变量,但反之则不行。
  • 这对于像 map(innerFunction) 这样的函数方法也很方便,其中 innerFunction 可以使用在外部作用域中定义的变量。

JavaScript 原型

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

尽管现代JavaScript 拥有相当复杂的类支持,但它仍然在幕后使用原型系统。这是该语言灵活性的主要来源。

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

在过去,使用下划线作为变量前缀的约定表示变量应该是私有的。然而,这只是一个建议,而不是平台强制的限制。现代 JavaScript 为类提供了哈希标记私有的成员和方法:

私有哈希名称是 JavaScript 中的一个较新且非常受欢迎的特性!最近的 Node 版本和浏览器都支持它,并且 Chrome 开发者工具允许您直接访问私有变量,以提高便利性。

使用闭包定义私有属性

另一种解决 JavaScript 原型系统中缺乏私有属性的方法是使用闭包。在上面的示例中,现代 JavaScript 允许您使用井号前缀定义私有属性。但是,这不适用于 JavaScript 原型系统。此外,这是您经常在代码中找到的技巧,了解它的作用很重要。

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

JavaScript 模块

从前,JavaScript 没有模块系统,开发人员设计了一个巧妙的技巧(称为模块模式)来实现一些可行的方案。随着 JavaScript 的发展,它不仅产生了一个模块系统,而是两个:CommonJS的include语法和ES6 的require语法。

Node 传统上使用 CommonJS,而浏览器使用 ES6。但是,Node 的最新版本(在过去几年中)也支持 ES6。现在的趋势是使用 ES6 模块,并且有一天我们将只有一种模块语法用于 JavaScript。ES6 看起来像这样(我们导出默认模块,然后导入它):

你仍然会看到 CommonJS,有时你可能需要使用它来导入一个模块。这是使用 CommonJS 导出然后导入默认模块的方式:

错误处理

无论您处于何种语言或环境中,错误处理都是必不可少且不可避免的。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 中以处理任何错误。)下面是一个处理异步错误的简单示例:

无论如何,切勿吞下错误!我不会在此处展示,因为有人可能会复制并粘贴它。基本上,如果您捕获到错误但什么也不做,程序将默默地继续运行,而没有任何明显的错误迹象。逻辑将中断,您将不得不思考,直到找到没有捕获块的 finally{}块。(注意,提供没有 catch 块的 finally{}块将导致错误被吞下。)

JavaScript 柯里化

柯里化是一种让函数更灵活的方法。使用柯里化函数,你可以传入函数期望的所有参数并获得结果,或者只传入参数的一部分,并得到一个等待其余参数的函数。这是一个简单的柯里化示例:

原始的 curry 函数可以通过在单独的一组括号中逐个传递每个参数来直接调用:

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

在实际使用中,当你需要创建许多根据某些参数而变化的函数时,这个想法可以提供帮助。

  1. JavaScript apply, call, and bind methods
  2. JavaScript 的 apply、call 和 bind 方法

虽然我们并不经常使用它们,但了解 call、apply 和 bind 方法还是很有好处的。在这里,我们将涉及到一些非常灵活的语言特性。这些方法的核心思想是允许你指定 this 关键字的解析对象。

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

在这三种方式中,调用是最简单的。它与调用函数时指定其上下文相同。这是一个示例:

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

bind 方法允许你在不调用函数的情况下向函数传递参数。一个新的函数将返回,其中参数被绑定在任何进一步的参数之前。这是一个例子:

JavaScript 记忆化

记忆化是一种优化技术,用于在多次调用相同的函数时,避免重复计算相同的函数结果。它通过缓存之前计算过的结果,并在下次需要相同结果时直接返回缓存的值,从而减少计算量和提高性能。

在 JavaScript 中,我们可以使用闭包来实现函数的记忆化。以下是一个示例:

function memoizedFunction(input) {
  // 创建一个对象来存储已经计算过的结果
  let cache = {};

  // 定义一个辅助函数,用于计算函数的结果
  function helper(input) {
    // 如果输入已经在缓存中,直接返回缓存的值
    if (input in cache) {
      return cache[input];
    }

    // 如果输入不在缓存中,计算函数的结果并将其存储在缓存中
    let result = compute(input);
    cache[input] = result;

    // 返回计算结果
    return result;
  }

  // 定义原始函数
  function compute(input) {
    // 这里是原始函数的实现,实际计算过程可能会很复杂
    return input * 2;
  }

  // 返回记忆化后的函数
  return helper;
}

// 创建一个记忆化后的函数
let memoized = memoizedFunction(5);

// 第一次调用记忆化后的函数,计算结果并存储在缓存中
let result1 = memoized(10); 
console.log(result1); 

// 第二次调用记忆化后的函数,直接返回缓存中的结果
let result2 = memoized(10); 
console.log(result2); 

在这个示例中,我们创建了一个名为memoizedFunction的函数,它接受一个输入参数input。在函数内部,我们创建了一个对象cache来存储已经计算过的结果。然后,我们定义了一个辅助函数helper,它接受一个输入参数input。在helper函数中,我们首先检查输入是否已经在缓存中,如果在缓存中,直接返回缓存的值。如果输入不在缓存中,我们计算函数的结果,并将其存储在缓存中。最后,我们返回计算结果。

我们使用compute函数来定义原始函数的实现,实际计算过程可能会很复杂。在这个示例中,我们只是简单地将输入乘以 2 作为计算结果。

最后,我们创建了一个记忆化后的函数memoized,它返回一个新的函数。这个新的函数就是记忆化后的函数,我们可以使用它来计算输入的结果。

在示例中,我们第一次调用memoized函数,并传入10作为输入,计算结果并存储在缓存中。然后,我们第二次调用memoized函数,并传入10作为输入,直接返回缓存中的结果。这样,我们避免了重复计算相同的函数结果,从而提高了性能。

Memoization是一种优化技术,通过存储昂贵操作的结果并在再次出现相同输入集时返回缓存的结果来加快函数执行速度。JavaScript 对象的行为类似于关联数组,这使得在 JavaScript 中实现备忘录变得很容易。以下是如何将递归阶乘函数转换为备忘录阶乘函数:

JavaScript立即执行函数表达式

立即调用函数表达式(IIFE)是一种在创建时立即执行的函数。它与任何事件或异步执行都没有关系。你可以按照如下方式定义一个 IIFE:

第一对圆括号 function() {...} 将括号内的代码转换为一个表达式。第二对圆括号调用该表达式得到的函数。IIFE 也可以被描述为一个自调用的匿名函数。它最常见的用法是限制 var 声明的变量作用域,或者封装上下文以避免名称冲突。

也有一些情况下,你需要使用 await 调用一个函数,但你不在 async 函数块内。这种情况有时会出现在你希望直接可执行且也作为模块导入的文件中。你可以将这样的函数调用包装在一个 IIFE 块中,如下所示:

有用的参数特征

虽然 JavaScript 不支持方法重载(因为它可以处理函数上的任意数量的参数),但它确实有几个强大的工具来处理参数。首先,你可以为函数或方法定义默认值:

你也可以一次性接受和处理所有参数,这样你就可以处理传入的任意数量的参数。这使用了剩余操作符来收集所有参数到一个数组中:

如果你真的需要处理不同的参数配置,你总是可以检查它们:

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

结论

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

这里讨论的 10 个 JavaScript 概念是每个 Node 开发人员都将受益于了解的基础知识。但它们只是冰山一角。JavaScript 是一种功能强大且复杂的语言。你使用它的次数越多,就越能理解 JavaScript 实际上有多么广泛,以及可以用它来做多少事情。

相关推荐

自学Python,写一个挨打的游戏代码来初识While循环

自学Python的第11天。旋转~跳跃~,我~闭着眼!学完循环,沐浴着while的光芒,闲来无事和同事一起扯皮,我说:“编程语言好神奇,一个小小的循环,竟然在生活中也可以找到原理和例子”,同事也...

常用的 Python 工具与资源,你知道几个?

最近几年你会发现,越来越多的人开始学习Python,工欲善其事必先利其器,今天纬软小编就跟大家分享一些常用的Python工具与资源,记得收藏哦!不然下次就找不到我了。1、PycharmPychar...

一张思维导图概括Python的基本语法, 一周的学习成果都在里面了

一周总结不知不觉已经自学Python一周的时间了,这一周,从认识Python到安装Python,再到基本语法和基本数据类型,对于小白的我来说无比艰辛的,充满坎坷。最主要的是每天学习时间有限。只...

三日速成python?打工人,小心钱包,别当韭菜

随着人工智能的热度越来越高,许多非计算机专业的同学们也都纷纷投入到学习编程的道路上来。而Python,作为一种相对比较容易上手的语言,也越来越受欢迎。网络上各类网课层出不穷,各式广告令人眼花缭乱。某些...

Python自动化软件测试怎么学?路线和方法都在这里了

Python自动化测试是指使用Python编程语言和相关工具,对软件系统进行自动化测试的过程。学习Python自动化测试需要掌握以下技术:Python编程语言:学习Python自动化测试需要先掌握Py...

Python从放弃到入门:公众号历史文章爬取为例谈快速学习技能

这篇文章不谈江流所专研的营销与运营,而聊一聊技能学习之路,聊一聊Python这门最简单的编程语言该如何学习,我完成的第一个Python项目,将任意公众号的所有历史文章导出成PDF电子书。或许我这个Py...

【黑客必会】python学习计划

阅读Python文档从Python官方网站上下载并阅读Python最新版本的文档(中文版),这是学习Python的最好方式。对于每个新概念和想法,请尝试运行一些代码片段,并检查生成的输出。这将帮助您更...

公布了!2025CDA考试安排

CDA数据分析师报考流程数据分析师是指在不同行业中专门从事行业数据搜集、整理、分析依据数据作出行业研究评估的专业人员CDA证书分为1-3级,中英文双证就业面广,含金量高!!?报考条件:满18...

一文搞懂全排列、组合、子集问题(经典回溯递归)

原创公众号:【bigsai】头条号:程序员bigsai前言Hello,大家好,我是bigsai,longtimenosee!在刷题和面试过程中,我们经常遇到一些排列组合类的问题,而全排列、组合...

「西法带你学算法」一次搞定前缀和

我花了几天时间,从力扣中精选了五道相同思想的题目,来帮助大家解套,如果觉得文章对你有用,记得点赞分享,让我看到你的认可,有动力继续做下去。467.环绕字符串中唯一的子字符串[1](中等)795.区...

平均数的5种方法,你用过几种方法?

平均数,看似很简单的东西,其实里面包含着很多学问。今天,分享5种经常会用到的平均数方法。1.算术平均法用到最多的莫过于算术平均法,考试平均分、平均工资等等,都是用到这个。=AVERAGE(B2:B11...

【干货收藏】如何最简单、通俗地理解决策树分类算法?

决策树(Decisiontree)是基于已知各种情况(特征取值)的基础上,通过构建树型决策结构来进行分析的一种方式,是常用的有监督的分类算法。决策树算法是机器学习中的一种经典算法,它通过一系列的规则...

面试必备:回溯算法详解

我们刷leetcode的时候,经常会遇到回溯算法类型题目。回溯算法是五大基本算法之一,一般大厂也喜欢问。今天跟大家一起来学习回溯算法的套路,文章如果有不正确的地方,欢迎大家指出哈,感谢感谢~什么是回溯...

「机器学习」决策树——ID3、C4.5、CART(非常详细)

决策树是一个非常常见并且优秀的机器学习算法,它易于理解、可解释性强,其可作为分类算法,也可用于回归模型。本文将分三篇介绍决策树,第一篇介绍基本树(包括ID3、C4.5、CART),第二篇介绍Ran...

大话AI算法: 决策树

所谓的决策树算法,通俗的说就是建立一个树形的结构,通过这个结构去一层一层的筛选判断问题是否好坏的算法。比如判断一个西瓜是否好瓜,有20条西瓜的样本提供给你,让你根据这20条(通过机器学习)建立起...