Java 开发人员对“JavaScript:好的部分”的评论

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

从一本关于编程语言的书的角度来看,经常被经常使用该编程语言的开发人员以崇敬的态度引用,可以说 Java Script:The Good Parts 之于 JavaScript 开发人员就像 Effective Java 之于 Java 开发人员一样。 Douglas Crockford JavaScript:The Good Parts 的副标题是“发掘 JavaScript 的卓越之处”。我终于购买并阅读了 JavaScript: The Good Parts O'Reilly / Yahoo! Press 2008 年 ),这是我对该书的评论。然而,这不仅仅是一篇评论,因为它还为我提供了一个论坛来突出我最感兴趣的那本书中的一些观点。

JavaScript: The Good Parts 是一本相对较短的书,只有 150 页,只有十章和五个附录。令人印象深刻的是,150 页可以压缩多少内容,并提醒人们最好的写作(散文和代码)往往是用更少的文字表达更多的内容。在一个多小时的飞行中,我能够阅读我最感兴趣的所有章节和两个附录(尽管我一坐上飞机就开始阅读)。有一点需要注意:尽管 JavaScript:The Good Parts 的某些部分对于基本熟悉 JavaScript 的人来说是一本非常快速的读物,但其他部分需要我重新阅读它们,甚至告诉自己,“我最好稍后回头再看再读一遍。”这是本书让我想起 Effective Java 的另一种方式。

前言

前言的第一页是该部分的核心内容,它概述了 JavaScript 的读者应该期待的内容。前言将 JavaScript 描述为“一种令人惊讶的强大语言”,它具有一些“提出一些挑战”的“非常规性”,但也是一种“易于掌握”的“小型语言”。本书针对的一类开发人员是“一直在使用 JavaScript 的新手级别的程序员,现在已经准备好与该语言建立更复杂的关系”。听起来像我!

Crockford 使用前言来描述 JavaScript: The Good Parts 涵盖的内容。他说:“我的目标是帮助您学会用 JavaScript 思考。”他还指出, JavaScript: The Good Parts “不是一本适合初学者的书”,“不是一本参考书”,“没有详尽地介绍这门语言及其怪癖”,“不是一本给傻瓜的书”,并且“很稠密。”

第 1 章:好的部分

JavaScript:好的部分 的第一章中,Crockford 指出编程语言有“好的部分和坏的部分”,并且“JavaScript 是一种有很多坏部分的语言”。他指出,这些缺陷主要是由于 JavaScript 的创建时间短,并明确表示,“JavaScript 的流行几乎完全独立于它作为编程语言的质量。” Crockford 发现,只要尽可能多地使用该语言的优点,开发人员就可以用任何语言编写出更好的程序。对于 JavaScript 来说尤其如此。 Crockford 提供了 JavaScript 好的部分的高级描述:

“JavaScript 有一些非常优秀的部分。在 JavaScript 中,有一种美丽、优雅、高度表达的语言,但被埋在一堆热气腾腾的善意和错误之下。”

在“分析 JavaScript”部分,Crockford 调查了 JavaScript 所基于的“非常好的想法”以及 JavaScript 所基于的“少数非常糟糕的”想法。第一章只有 4 页,而这些好的和坏的想法的概述包含在几页中。但是,本书的其余章节提供了有关好的部分的更多详细信息,而前两个附录提供了有关坏部分的更多详细信息。

我同意 Crockford 的断言,即对 JavaScript 的很大一部分消极甚至敌意可能更恰当地针对 DOM。 JavaScript 可能被指责为非标准和特定于浏览器数百万次,而实际上是浏览器的 DOM 实现是非标准和特定于浏览器的。

如果不引用一句更精明的话,我无法完成对 JavaScript:The Good Parts 第一章的评论:“[鉴于 JavaScript 的]许多错误和尖锐的边缘,......'我为什么要使用 JavaScript?'有两个答案。第一个是你别无选择。......JavaScript 是所有浏览器中唯一的语言。......另一个答案是,尽管存在缺陷,但 JavaScript 确实很好 。”

第 2 章:语法

JavaScript 的第二章:The Good Parts 提供了 15 页的介绍“JavaScript 的优秀部分的语法,快速概述了该语言的结构”。对于以前使用过 JavaScript 的人来说,本章的大部分内容可能不是特别有见地,尽管仅仅看到 Crockford 认为“好”的语言部分是有用的。 “语句”部分早先指出了 JavaScript 的一些“非常规”方面:由大括号划定的代码块不会限制这些块的范围,并且变量应该在函数的开头定义,而不是在第一次使用时定义。

第 3 章:对象

第 3 章的 6 页介绍了 JavaScript 对象。 JavaScript 对象的重要方面(键/值对性质、原型对象关联、按引用传递、使用 typeof hasOwnProperty 进行异议检查以及减少对象的“全局足迹”)都得到了简洁的介绍。

第 4 章:函数

JavaScript 的第 4 章:好的部分 开头是这样的陈述:“JavaScript 最好的地方在于它的函数实现。它几乎做对了所有事情。但是,正如您对 JavaScript 应该期望的那样,它并没有做对所有事情。”本章比之前的章节更长(20 页),进一步强调了 Crockford 认为函数是 JavaScript 真正优秀的部分之一。尽管它比前面的章节更长,但在我看来,第 4 章也更密集(特别是比第 2 章和第 3 章)。

第 4 章对 JavaScript 函数的介绍指出了我需要接受的 JavaScript 差异之一,以便对这门语言更有信心:“JavaScript 中的函数是对象”。 函数调用 部分简要描述了 JavaScript 中的四种调用模式( 方法调用 函数调用 构造函数调用 应用调用 ),并解释了 this 根据所使用的特定调用模式 进行不同的初始化。 JavaScript 的 this 取决于上下文的不同含义一直是从 Java 背景转为使用 JavaScript 的更困难的方面之一,但这个解释是我读过的最清晰和最容易记住的。

第四章涵盖异常处理、方法级联和类型扩充。 “增强类型”部分展示了多个示例,这些示例通过向适当的原型添加方法来“增强基本类型”来添加“对语言表达能力的显着改进”。

关于“递归”、“闭包”和“模块”的部分对我来说有点密集,我需要不止一次阅读这些部分的几个部分才能更充分地理解所提出的观点。我相信我还有一段路要走才能完全理解这些概念,但我也相信很好地理解它们并实现这里介绍的模块概念是在大规模 JavaScript 开发中获得快乐的关键。

第 4 章的“Curry”部分指出 JavaScript 缺少 curry 方法,但解释了如何通过将 curry 方法与 Function 相关联来解决这个问题。 “记忆”部分演示了如何在 JavaScript 中使用 记忆 ,以便“函数可以使用对象来记住先前操作的结果,从而避免不必要的工作。”

第 5 章:继承

JavaScript: The Good Parts 的第五章首先简要解释了继承在“经典语言(如 Java)”中提供的两个“有用服务”:代码重用和类型系统。据解释,JavaScript 是动态类型的,因此从继承中获得了一个优势:代码重用。 Crockford 表示“JavaScript 提供了比“经典模式”更丰富的代码重用模式集”。

第 5 章的“伪经典”部分以“JavaScript 在其原型性质方面存在冲突”这一断言开始。对使用构造函数调用模式的危险和缺点进行了深入讨论。最“严重的危害”发生在开发人员在调用构造函数时忘记使用 new 时。 Crockford 警告说,在这种情况下, this 与全局对象相关联,而不是(可能)预期的新对象。作者指出,惯例是使用大写字母作为“构造函数”对象的第一个字母来指示这种风险,但他建议更好的做法是根本不使用 new 或构造函数调用模式。

第 5 章“伪经典”部分的讨论提供了有关 Crockford 在第 4 章中提出的“构造函数调用模式”问题的更多细节。这两部分迫使我承认虽然我喜欢在 JavaScript 中使用构造函数调用模式,只是因为“伪经典形式可以为不熟悉 JavaScript 的开发人员提供安慰”。克罗克福德警告说,它的使用“隐藏了语言的真实本质”。

第 5 章介绍了对象说明符,并深入介绍了 JavaScript 的原型实现和差异继承。第五章的“功能”部分说明了如何使用功能方法进行重用,并指出这种功能方法“比伪经典模式需要更少的努力,并为我们提供了更好的封装和信息隐藏以及对超级方法的访问。”第五章以“部分集合”组合对象的讨论和代码示例作为结尾。

第 6 章:数组

长达 6 页的 JavaScript 第六章:The Good Parts 介绍了数组的概念并提到了它的一些好处,但遗憾的是,“不幸的是,JavaScript 没有这种数组。”作者将 JavaScript 所提供的描述为“具有某些类似数组特征的对象”。他指出,这个类似数组的对象“比真正的数组慢得多,但使用起来更方便”。

第 6 章讨论了 JavaScript 用于 JavaScript“数组”的“非常规” length 属性,并介绍了访问元素、 push delete 的语法。 Crockford 指出“JavaScript 没有区分数组和对象的良好机制”,他提供了 is_array 函数的两个简短实现(第二个依赖于 toString() 未被覆盖)。

第六章以关于向 JavaScript 的 Array 添加方法的讨论结束。具体的代码示例包括一个初始化 JavaScript 数组元素的函数和一个初始化矩阵(数组的数组)元素的函数。

第 7 章:正则表达式

将近 23 页的 JavaScript: The Good Parts 的第七章重点介绍了在 JavaScript 中应用正则表达式。对于那些使用过正则表达式的其他实现(特别是 Perl 或基于 Perl 的实现)的人来说,这将是相当熟悉的。

Crockford 指出了保持正则表达式简单的几个动机,但他引用的 JavaScript 特定的更简单正则表达式的动机与不同 JavaScript 语言处理器的正则表达式支持之间缺乏可移植性有关。

第 7 章介绍了在 JavaScript 中创建正则表达式的两种形式:文字( / 语法)和 RegExp 构造函数。本章还介绍了其他 JavaScript 语法,用于处理 JavaScript 中的各种正则表达式概念。

第 8 章:方法

JavaScript 第 8 章的 15 多页:好的部分 感觉像是 API 参考,让我想起了 Java in a Nutshell 等书。这些页面总结了 JavaScript 中“标准类型上可用的一小组标准方法”。本章列出了方法签名、简要方法描述,以及将该方法用于在 Array Function Number Object RegExp String 上定义的标准方法的示例。尽管这些是很好的总结描述和示例用法,但考虑到这些 API 在诸如 Mozilla Developer Network JavaScript Reference 等站点中在线记录,这一章可能是本书中最没有用的一章。

第9章:风格

JavaScript:The Good Parts 对我来说最(愉快)令人惊讶的一章可能是第 9 章。当我浏览目录并看到“风格”时,我认为这一章将是另一个平淡无奇的拼写,说明该做什么和不该做什么在代码中做风格。我厌倦了这些风格化的讨论。这一章不到4页,所以没想到太多。

事实证明,第九章在其关于风格的三页多一点的地方有一些重要的观察。我喜欢 Crockford 将风格问题与任何编程语言联系起来的原因,并强调它们在 JavaScript 中尤为重要。

第 9 章中我最喜欢的部分是 Crockford 解释他在本书中用于 JavaScript 代码的风格。其中一些是平淡无味的东西,例如缩进的空格数,但其中一些是出于对 JavaScript 细微差别和局限性的理解。例如,Crockford 指出,“我总是使用 K&R 风格 ,将 { 放在行尾而不是行首,因为它避免了 JavaScript 的 return 语句中可怕的设计错误。”同样,他指出他在函数的开头声明变量,并且由于 JavaScript 的其他细微差别,他更喜欢行注释而不是块注释。他(和我的评论)在附录中详细介绍了这些内容。

倒数第二章提供了一些关于编码风格和大型 JavaScript 应用程序的尖锐建议:

“在 JavaScript 的设计、实现或标准化中,质量并不是一个令人兴奋的问题。这给语言的用户带来了更大的负担来抵制语言的弱点。JavaScript 为大型程序提供支持,但它也提供了形式和习语针对大型程序工作。

第 10 章:美丽的特征

JavaScript 的坏特性是附录 A(“不容易避免的”“糟糕的部分”)和附录 B(“很容易避免的”“有问题的特性”)的重点,但 Crockford 将第 10 章的重点放在他认为 JavaScript 的“美丽之处”特征。”因为这是本书的主题,本章只需要 2 页多一点就可以突出 Crockford 的“简化 JavaScript”概念:取 JavaScript 的“最好的部分”,用很少或很少的东西去除语言的特性。甚至是负值,并添加了一些新特性(比如块作用域,这可能是我在 JavaScript 中最怀念的东西)。

附录 A:糟糕的部分

附录 A 在 7 页多的篇幅中突出显示了“JavaScript 中不容易避免的有问题的特性”。克罗克福德警告说,“你必须意识到这些事情并做好应对的准备。”

附录的正文以一个难以反驳的断言开头:“JavaScript 的所有坏特性中最糟糕的是它对全局变量的依赖。”我也喜欢 Crockford 指出虽然许多编程语言“有全局变量”,但 JavaScript 的问题在于它“需要它们”。

附录 A 还强调了为什么 JavaScript 对保留字的处理、缺少块作用域、16 位 unicode 支持、 typeof 限制、没有显式基数的 parseInt 、混淆 + 以添加或连接、“虚假”数组和其他一些特性是有问题的以及如何避免或减少它们的使用。

也许附录 A 中对我来说最有趣的讨论是解释为什么 JavaScript 有时会插入分号,而不是修复问题,这会使事情变得更糟(掩盖更重要的代码问题)。

附录 B:坏零件

附录 B 的六页“介绍了 JavaScript 的一些容易避免的问题特性”。本章详细说明了为什么应避免使用 == with continue 、falling through switch 、无块语句、按位运算符、类型化包装器(以及 new Object new Array )和 void 等 JavaScript 特性。

附录 C:JSLint

附录 C 提供了 10 页重点介绍 JSLint ,它被描述为“JavaScript 语法检查器和验证器”。关于 JSLint,Crockford 指出,“JSLint 定义了 JavaScript 的一个专业子集……与第 9 章中的风格建议相关。JavaScript 是一种草率的语言,但在它内部有一种优雅、更好的语言。JSLint 可以帮助你用那种语言进行编程更好的语言并避免大部分污点。”

附录 C 详细介绍了 JSLint 如何帮助 JavaScript 开发人员识别全局变量和函数,识别可能拼写错误的成员(只使用一次,因为拼写错误但 JavaScript 本身不会报告),识别丢失或无关的分号,识别由于不正确的行而自动插入分号的潜在问题中断,并识别缺少左花括号和右花括号的块语句。 JSLint 标记的其他项目包括 fall-though switch 语句、 with 的使用、条件表达式中使用的赋值运算符、使用 == != 的潜在 JavaScript 类型强制转换、 eval void 、按位运算符、可能不可移植的正则表达式,以及构造函数。

本章还演示了如何向 JSLint 指定“可接受的 JavaScript 子集”。换句话说,可以选择不让 JSLint 标记某些条件。我发现有趣的是,除了检查格式正确的 JSON 之外,JSLint 还提供了一些 HTML 验证。

我发现 Java 的静态代码分析工具不仅有助于改进现有的 Java 代码,而且在我了解什么被认为是错误或不良形式、为什么错误或不受欢迎以及如何躲开它。 JSLint 对 JavaScript 的影响也是如此;学习 JavaScript 的人可以从学习 JSLint 标记的内容中获益,以了解 JavaScript 的不良/丑陋部分以避免……

附录 D:语法图

第四个附录仅包含语法图,以图形方式指示各种 JavaScript 结构是如何在语法上构建的。这些图表是 JavaScript 中突出显示的 JavaScript 部分:好的部分 。附录 D 是类似于第 8 章的参考指南,并且与第 8 章一样,可能是本书附录中最没有价值的,因为它是很容易在网上获得的信息。

附录 E:JSON

本书的最后十页在附录 E 中,专门介绍 JavaScript 对象表示法 (JSON)。附录将 JSON 描述为“基于 JavaScript 的对象文字表示法,这是 JavaScript 最好的部分之一”。这篇介绍解释了 JSON 是一种基于文本的格式,它是 JavaScript 的一个子集,但也可以用作一种独立于语言的数据传输格式。本附录中的大部分材料在 2008 年本书出版时对人们来说显然比现在新得多,因为今天许多甚至不太了解 JavaScript 的开发人员都知道 JSON。

附录 F 在大约一个页面中描述了 JSON 的语法规则,因为“JSON 的设计目标是最小的可移植性、文本和 JavaScript 的子集。”

附录 F 关于“安全使用 JSON”的部分着眼于使用 JavaScript 的 eval 将 JSON 转换为有用的 JavaScript 数据结构的风险,并建议改用 JSON.parse 。还有一个有趣的讨论是关于将服务器发送的 HTML 文本片段分配给 HTML 元素的 innerHTML 属性的安全隐患。有趣的是 Crockford 指出这个安全问题与 Ajax XMLHttpRequest 或 JSON 无关,而是由于以全局对象为特色的核心 JavaScript 设计缺陷。 Crockford 对这个“特性”进行了进一步的分析:“这种危险是 JavaScript 的全局对象的直接后果,它是 JavaScript 的许多不良部分中最糟糕的部分。......这些危险从一开始就存在于浏览器中的 JavaScript,并将一直保留到 JavaScript 被替换。小心。”

附录 F 的最后 5 1/2 页包含一个用 JavaScript 编写的 JSON 解析器的代码清单。

一般观察

  • JavaScript: The Good Parts 值得赞美和崇敬;这是一本很棒的书,我想不出我读过的一本 JavaScript 书对我理解这种非常规语言所做的贡献与 JavaScript: The Good Parts 一样多。
  • 许多技术书籍对所涵盖的语言、框架或库赞不绝口,要么不承认所涵盖项目的缺陷和缺点,要么迅速将其解释为微不足道或无关紧要。 JavaScript: The Good Parts 更有效,因为它不这样做。相反,Crockford 的文章清楚地表明,他喜欢 JavaScript 的许多方面并发现其富有表现力,但他也认识到它的缺点。他的书试图教导人们如何主要只使用 JavaScript 的好的部分,而尽量避免使用 JavaScript 的坏部分。
  • 因为 Crockford 花时间解释 JavaScript 的非常规特性并区分非常规方法“好”的情况和非常规方法“坏”的情况,所以本书的读者有更好的机会欣赏 JavaScript 的积极因素,而不是主要看到它的消极因素。
  • JavaScript: The Good Parts 强化了这样一种观点,即试图像对待 Java(或任何其他经典的面向对象语言)一样对待 JavaScript 是错误的。它解释了为什么这种方法经常导致 JavaScript 受挫。
  • JavaScript: The Good Parts 是一本可读性强且通俗易懂的书。这本书的(英语)语言清晰,写得很好。简明扼要令人印象深刻,尤其是考虑到本书的一些最重要的观点在不同的上下文中被多次提及,而且整本书的主要页数不到 150 页。
    • 尽管 JavaScript: The Good Parts 以一种非常易读的形式编写,但其中的某些部分更难阅读,因为内容更难。在第 4 章有关函数的某些部分中尤其如此。其中一些部分需要我多次阅读,但它们也是在理解时带来最多洞察力的部分。
    • JavaScript: The Good Parts 如此简洁的原因之一是它提供的介绍很少。那些以前从未编码或没有 JavaScript 编码经验的人,可能最好先阅读更具介绍性的书籍或在线资源。
  • JavaScript: The Good Parts 中提供了几个有用的 JavaScript 代码片段来说明 JavaScript 的好的和坏的部分。在此过程中,提供了几段通用且可重用的代码,值得在此处强调:
    • 第 3 章(第 22 页)提供了 6 行代码,用于将“ create 方法”与“创建一个使用旧对象作为其原型的新对象”的 Object 函数相关联。
    • 第 4 章(第 32-33 页)提供了 4 行代码,用于使命名方法可用于所有函数。一个略微修改的版本在一页后出现,添加了“防御技术”以确保新定义的方法不会覆盖另一个库已经使用的方法。
    • 第 4 章(第 33 页)提供了 3 行代码,用于将 integer 添加到 Number.prototype ,“仅提取数字的整数部分”。
    • 第 4 章(第 33 页)提供了 3 行代码,用于将 trim 方法添加到 String.prototype ,“从字符串的末尾删除空格”。
    • 第 4 章(第 44 页)提供了 8 行代码,用于向 Function 添加 curry 方法。
    • 第 4 章(第 45 页)提供了 11 行代码,这些代码实现了用于生成记忆函数的通用函数。
    • 第 5 章(第 54 页)提供了 7 行代码,这些代码实现了一个 superior 方法,该方法“采用方法名称并返回调用该方法的函数”。
    • 第 6 章(第 61 页)提供了 is_array 函数的两个简短实现,用于确定给定的 JavaScript 项是否为数组。
    • 第 6 章(第 63 页)提供了对数组的 dim 方法的实现,该方法初始化数组的所有元素。
    • 第 6 章(第 63-64 页)提供了对数组 matrix 方法的实现,该方法初始化嵌套在数组中的数组的所有元素。
    • 附录 F(第 140-145 页)提供了一个“简单、递归的 [JSON] 解析器”的实现,用于从 JSON 文本生成 JavaScript 数据结构。
  • JavaScript: The Good Parts 这样的书必然是固执己见的(这同样适用于优秀的 Effective Java )。我喜欢这种情况,因为它不是片面的、有色眼镜的意见,而是表达了对 JavaScript 好的和坏的部分的意见。并非所有意见都是平等的。在这种情况下,作者道格拉斯·克罗克福德 (Douglas Crockford) 以极大的可信度来支持他的观点。他对 JSLint 和 JSON 的参与足以说明他在 JavaScript 方面的经验和知识。没有经验的人写的有主见的书不太可能很有价值,但有经验的开发人员写的有主见的书通常是最有价值的技术书籍之一。

结论

JavaScript: The Good Parts 是那些相对罕见的技术书籍之一,它被大肆宣传并且不负众望。它帮助读者了解如何使用 JavaScript 的最佳部分,避免或减少接触 JavaScript 的不良部分。在这样做的过程中,它确实帮助读者做到了作者试图完成的事情:用 JavaScript 思考。 JavaScript: The Good Parts 将重要的底层细节和重要的高级语言设计讨论压缩到不到 150 页。