发布于 2026-01-06 0 阅读
0

我对 JavaScript 的爱恨交织 我喜欢 JavaScript 的地方 我不喜欢 JavaScript 的地方 吹毛求疵之处 结论

我对 JavaScript 的爱恨交织

我喜欢 JavaScript 的地方

我不喜欢 JavaScript 的地方

吹毛求疵

结论

原文发表于deepu.tech

程序员大致可以分为三种:喜欢 JavaScript 的、讨厌 JavaScript 的,以及两者兼而有之的。JavaScript 是我学习的第二门语言(第一门是 C/C++),当时我正在尝试搭建我的 WordPress 博客,甚至在我开始职业生涯之前。我的工程职业生涯是从 Java Web 应用开发开始的,这意味着我也有机会使用 JavaScript 进行前端开发。我对 JS/HTML/CSS 非常精通,很快就开始开发大量以前端为主的 Java Web 应用。我还学习了 jQuery,并深深地爱上了它。

在我职业生涯的最初几年,JavaScript 无疑是我最喜欢的语言,因为它极其灵活易用,尤其是在我想快速搭建一些小项目的时候,尽管我也用 Java 写了很多代码。以前那个不成熟的我甚至认为 JavaScript 是世界上最好的编程语言,而且我会和任何认为 JavaScript 不好的人激烈争论,毕竟我当时确实有一些理由这么认为。现在,我觉得自己更成熟了,为了更加务实,我开始以更客观、更公正的眼光看待各种语言和框架。现在我不会说 JavaScript 是最好的语言,但它非常重要,我知道它的缺点,也承认 JS 生态系统中存在一些我不喜欢的地方。

别误会,我仍然热爱 JavaScript(尤其热爱 TypeScript),我见证了从 jQuery 到如今 MVVM 框架的兴衰,并且几乎都用过。JavaScript 既是最受喜爱的语言之一,也是最受诟病的语言之一。你可能会注意到,我喜欢 JavaScript 的很多方面,同时也是我很讨厌的方面,这也是我标题的由来。在与 JavaScript 及其庞大的生态系统打交道十余年后,以下是我对这门语言的一些看法。请注意,其中很多观点都基于个人偏好,因此可能略带偏见。


我喜欢 JavaScript 的地方

首先,让我们来谈谈我喜欢 JavaScript 的地方。

既适合新手又功能强大

JavaScript 是最适合初学者的语言之一。尽管它有一些特性,但入门非常容易。你甚至不需要安装或设置任何东西。只要你的电脑上有网络浏览器,就可以开始编写 JavaScript 代码了。互联网上还有海量的学习资源。它的基本语法非常简单,基本概念也很容易理解。但这并不意味着它是一种简单的语言,我们稍后会讨论这一点。

JavaScript 也是一种非常强大的语言,几乎可以完成任何事情,例如构建网页、服务器应用、移动应用、机器人等等(但这并不意味着你应该这么做😜)。我还没见过其他任何语言能像 JavaScript 一样用途广泛。但请记住,学习 JavaScript 很容易,但成为一名优秀的 JavaScript 开发人员却相当困难。

充满活力且极其灵活

JavaScript 是我用过的最动态的语言,它能做到很多其他语言想都不敢想的事情。JavaScript 非常宽容,所以你可以尽情发挥。运行时更改变量类型?没问题;向你无法控制的类添加变量和方法?没问题;编写能生成代码的代码?没问题。这样的例子不胜枚举。这种动态特性在某些应用场景下非常有用,例如脚本编写或模板引擎。

但这并非没有代价。灵活性既是 JavaScript 最大的优势,也是它最大的劣势。在编写脚本等方面,灵活性极其便捷,但也意味着在大型代码库中维护起来更加困难,我们将在“缺点”部分详细讨论这一点。

在我的职业生涯中,我花费了大量时间来创建原型和概念验证,JavaScript 的动态特性和灵活性使这项工作变得高效便捷,但我绝不会建议将它们用于需要维护的实际应用程序。

例如,您可以使用以下 JavaScript 代码来构建动态函数。

const functions = {};

for (let i = 0; i < 10; i++) {
  functions[`myAwesomeFunc${i}`] = new Function("fnName", `console.log('Hello world from ' + fnName + ' fn created by index ${i}');`);
}

Object.values(functions).forEach((fn) => {
  fn(fn.name);
});

// prints
// Hello world from anonymous fn created by index 0
// ...
// Hello world from anonymous fn created by index 9
Enter fullscreen mode Exit fullscreen mode

多范式

JavaScript 最初是一种命令式脚本语言,后来添加了许多特性,使其能够支持面向对象编程 (OOP)。由于它拥有丰富的特性,你也可以将其用作函数式编程语言。我喜欢这种语言的这种特性,因为它允许你融合各种编程范式的优点,从而高效地完成工作。

履行一等公民的职责

在 JavaScript 中,函数是一等公民,它们与其他类型的对象并无二致。你可以传递函数、在运行时创建函数、修改函数、存储函数等等。你甚至可以为函数添加属性。

function foo(msg) {
  console.log(`Hello world! ${msg}`);
}

foo.bar = "Yo";

foo(foo.bar); // prints 'Hello world! Yo'
Enter fullscreen mode Exit fullscreen mode

有用的语法糖(个人偏好)

JavaScript 提供了许多实用的语法糖,例如 async/await、扩展运算符/剩余运算符、解构赋值、三元运算符等等,我非常喜欢它们,因为它们能让代码更简洁易懂。当然,如果你是 JavaScript 新手,它们可能会让你感到有些困惑。

元编程

JavaScript 对元编程提供了强大的支持。它提供了 ` Proxyand`Reflect对象,允许你拦截现有语言运算符并为其定义自定义行为。这无疑是一项高级功能,拥有其独特的应用场景。

语法简洁明了(个人偏好)

我可能有点偏见,因为JavaScript和Java是我接触最多的语言,所以在语法方面,我可能不自觉地觉得它们更友好。当然,用JavaScript写出难以阅读的代码也是有可能的,但同时你也可以写出优美且富有表现力的代码,而且我发现JS的语法比很多其他语言都更易读。

可以跑遍任何地方

从技术上讲,JavaScript 几乎可以在任何地方运行。它无疑是世界上最大的编程平台,尤其是在互联网时代,因为 JavaScript 是 Web 的语言。你可以在浏览器、移动设备、服务器端、桌面应用程序、操作系统、物联网设备、机器人、虚拟现实设备、智能手表等各种环境中运行 JavaScript,也可以从其他语言(例如 Java)中调用它。

这是Anil Dash撰写的一篇关于这个话题的有趣文章。

最大的社区

JavaScript 拥有最庞大的社区,毕竟它是最流行的编程语言。NPM 仓库中的软件包数量比大多数其他语言的总和还要多,而且你很容易在网上找到任何与 JavaScript 相关的帮助。围绕 JavaScript 构建的庞大生态系统使其非常易于使用。无论你有什么需求,你都可以确信总能找到相应的 JavaScript 库或工具。

JS模块计数

只要网络浏览器和互联网存在,JavaScript 就会存在。

每当有人说Java和JavaScript就像恐龙(老旧、过时、笨重)时,我都会试图纠正他们。在我看来,JS和Java就像蟑螂,它们几乎无所不能。而且我确信,除非互联网行业发生翻天覆地的变革,否则JavaScript在可预见的未来仍将存在。所以,你的JS技能仍然非常重要,因此掌握它是一项重要的技能。

NodeJS

JavaScript 社区发展壮大的原因之一也归功于 NodeJS。它为 JavaScript 走出浏览器、走向更广阔的领域铺平了道路,而这带来了爆炸式增长。我喜欢 NodeJS,因为它让任何人都能轻松构建并向社区发布可重用的软件包。当然,NodeJS 也存在一些问题,例如碎片化和臃肿,但它仍然是程序员工具箱中不可或缺的重要工具。

TypeScript

你可能会说 TypeScript 是一种独立的语言,但从技术上讲,它是 JavaScript 的语法超集,因此我更愿意把它放在这里。TypeScript 解决了 JavaScript 中许多常见的问题,例如对静态类型的支持、可扩展性等等。所以,我肯定会把它列入“喜欢”的行列。我希望每个 JavaScript 运行时都能原生支持 TypeScript(例如Deno),或者 JavaScript 最终能够演化成 TypeScript(那将非常棒)。

我不喜欢 JavaScript 的地方

现在我们来谈谈我不喜欢 JavaScript 语言和生态系统的地方。

碎片化(浏览器实现、版本兼容性)

对我来说,JavaScript最大的问题是碎片化。JS模型允许最终用户选择实现方式,这意味着程序员对自己的代码将在哪个实现上运行几乎没有控制权。在实现方面,主要有两个方面需要考虑;

厂商:市面上存在太多不同的 JavaScript 引擎,它们的实现方式略有不同,这让程序员苦不堪言。例如,Chrome、Node.js、Opera 等浏览器都使用 V8 引擎,而 Mozilla 则使用 SpiderMonkey,苹果使用 JavaScriptCore,等等。
问题在于,ECMAScript 标准并没有提供 JavaScript 的参考实现,厂商们为了满足自身需求,会对实现细节进行细微的修改,导致同一段代码在不同的引擎中表现各异。还记得 Internet Explorer 吗?过去二十年里,很大一部分前端代码都是为了兼容浏览器而编写的,比如 jQuery 代码库中很大一部分就是为了让它在 Internet Explorer 中运行。虽然我很高兴 IE 浏览器终于​​停止维护了,但对于开发 JavaScript 应用的人来说,这些不同的实现方式仍然会不时地引发一些难以察觉的 bug。

版本:造成碎片化的另一个原因是 ECMAScript 版本。厂商们随意地实现不同的版本,导致开发者无法依赖任何特定版本,因为他们无法确定最终用户的浏览器是否支持该版本。这就催生了像 Babel 这样的中间层工具,它们会将你的代码转译成通用标准(通常是 ES5),从而增加了复杂性和开销。

由于这些因素,如今仍然存在的最大问题之一是 JS 模块系统,每个人都使用模块系统(requireJS、commonJS 或 ES 模块),但对于标准实现方式仍未达成共识,这令人非常沮丧。

这或许就是为什么JS是唯一拥有像caniuse.com这样专门网站的语言的原因。

我希望有一个由社区管理、所有浏览器和运行时环境都使用的单一引擎,这样就能减少碎片化问题。

官僚机构

JavaScript 作为一个庞大的社区,拥有类似于 Java 的自身官僚体系和流程层。它有不同的管理机构,例如 ECMA International、ISO、JS Foundation、W3C 等,这些机构都对 JavaScript 的未来有着切身利益。此外,还有不同的浏览器厂商,例如 Google、Mozilla 和 Apple,它们都有各自的计划。所有这些都使得 JavaScript 语言的发展缓慢、混乱且痛苦。

语言怪癖

有时候我真怀疑JavaScript是不是某人嗑了迷幻药(LSD)加摇头丸之后设计的,因为这门语言里有些怪异之处简直让人匪夷所思。我觉得其他任何语言都不会有这么多怪异之处,这也让JavaScript的批评者们找到了不少攻击的把柄。

有一个专门的仓库用于记录这个:https://github.com/denysdovhan/wtfjs

这里举个例子,别试图理解这里发生了什么。

console.log((![] + [])[+[]] + (![] + [])[+!+[]] + ([![]] + [][[]])[+!+[] + [+[]]] + (![] + [])[!+[] + !+[]]);
// prints 'fail'
Enter fullscreen mode Exit fullscreen mode

Npm地狱

NodeJS 对 JavaScript 社区来说就像是天赐之物,它催生了 NPM,NPM 如今发展迅猛,但同时也成了 JavaScript 开发者们不得不忍受的烦恼。你有没有试过查找一个node_modules文件夹中的文件数量?

NPM 是一个不错的包管理器,它有一些非常棒的功能,例如npm link……但它嵌套的依赖结构以及灵活的版本控制,使其成为灾难的根源,并会导致无数痛苦的调试时间。此外,还有一个问题,那就是庞大的注册表中包含了如此多应用程序使用的众多软件包。还记得Leftpad吗?

容易出错(灵活性的副作用)

使用 JavaScript 很容易搬起石头砸自己的脚。确切地说,JavaScript 会给你提供 100 种不同的上膛枪,它会在你瞄准时牵着你的手,如果你犹豫,它还会扣动扳机。一旦你打中了自己的脚,它就会砍掉你的腿,让你把它吃掉。我本来不想用这么血腥的比喻,但 JavaScript 就是这样。这很大程度上是因为 JavaScript 最初的设计并非为了应对如今的规模。它最初只是一种简单的动态脚本语言。由于 JavaScript 过于动态和灵活,它允许你做很多其他语言无法做到的事情,再加上它本身就有很多怪癖,所以 bug 随时都可能出现。

如今情况已经大为改观,新版本和 ESList、VSCode、TypeScript 等众多工具的出现,极大地帮助我们避免了常见错误。但即便如此,编写大型 JavaScript 程序而不出现隐蔽 bug 仍然需要丰富的经验和辛勤的付出。在我的职业生涯中,我参与的大部分调试工作都与 JavaScript 有关。

又一个框架综合症

JavaScript 还有一种独有的现象,叫做“又一个框架综合症”。几乎每天都有新的框架和库被创造出来,这种频繁的更迭如此之快,以至于如果你离开 JavaScript 世界一年后再回来,你会发现自己什么都认不出来,而且还得学习一些新的框架。这意味着维护 JavaScript 应用的团队需要不断地将过时的框架迁移到新的框架,如此循环往复。在我的职业生涯中,我不得不花费大量时间从 jQuery 迁移到 AngularJS,从 AngularJS 迁移到 Angular,再从 Angular 迁移到 React 等等。相比之下,Java 的框架更迭速度就慢得多。JavaScript 社区似乎也比其他语言社区更容易受到“非我发明”综合症的影响,在这里,你几乎可以找到任何功能的十几种选择。

复杂

正如我之前所说,JavaScript 对初学者非常友好,也很容易学习,但它目前的版本并非一门简单的语言。它经历了巨大的发展,表面上的简洁背后隐藏着许多复杂的功能,而且还在不断扩展。由于其历史悠久且动态的特性,它有很多种实现同一功能的方法,而这正是我在任何语言中都不喜欢的。此外,它还拥有一个复杂的生态系统,想要大规模地使用 JavaScript,就必须学习相关的知识。例如,你需要学习 Webpack、NodeJS、NPM、Babel、ESLint 等等,才能高效地进行开发。

使用 JavaScript 的回调函数等技术很容易编写出复杂难读的代码,这通常被称为“回调地狱”!再加上 JavaScript 的动态特性和遗留问题,复杂性会不断增加。

可扩展性

JavaScript 本身完全不具备可扩展性。代码库规模较小时,开发效率会很高,但随着代码量的增长,问题就会接踵而至。由于缺乏类型系统,除非使用 TypeScript 之类的类型系统,否则大型代码库的维护将变成一场噩梦。即便如此,与其他语言相比,大型 JavaScript 代码库的遍历和维护仍然困难得多。例如,我在JHipster 项目上就深有体会。很快,你就会发现自己需要添加构建工具、代码检查器、转译器等等来简化维护工作。

吹毛求疵

嗯,说到 JavaScript,要么你很喜欢它,要么你很讨厌它,或者两者兼而有之,至少对我来说,没有什么真正的小瑕疵。


结论

如果你在网上搜索关于 JavaScript 的观点,你会发现海量的内容,有的赞扬它,有的抨击它,还有一些比较客观。关于 JavaScript 及其社区,有很多话要说。对大多数人来说,这是一种爱恨交织的关系,有些人甚至勇敢地承认这一点。

如果你真的非常讨厌 JavaScript,要么是你接触它的机会不多,要么是你对它抱有偏见。不妨试试看,它其实是一门很有趣的语言(至少能让你保持清醒😜),它有其存在的意义,而且不管你喜不喜欢,它都是现代 Web 的语言,并且在这方面表现出色。如果你认为用其他语言在 Web 开发方面效率更高,那么或许你应该尝试用那种语言构建一个大型网站,然后再学习 JavaScript 并进行同样的尝试。在我看来,JavaScript 的发展势头强劲,而且只会越来越普及,所以不学习这门最流行的语言是愚蠢的。每个程序员都应该学习 JavaScript,你永远不知道它什么时候会派上用场。

如果你非常喜欢 JavaScript,并且什么都用 JavaScript 来做,那么或许你也应该学习一些其他语言,比如 Java、Go 或 Rust,你就会明白为什么 JavaScript 并不适合很多用例(当然,它能做到,任何图灵完备的语言都能做到,但这并不意味着你应该这样做)。

关键不在于知道如何使用 JavaScript,而在于知道何时使用 JavaScript,何时不使用 JavaScript。


如果您喜欢这篇文章,请点赞或留言。

你可以在TwitterLinkedIn上关注我。

封面图片来源:使用imgflip制作

文章来源:https://dev.to/deepu105/my-love-hate-relationship-with-javascript-3p66