本书由资深 JavaScript 技术专家 David Herman 所著。书中基于 JavaScript 标准的新版本前所未有地阐明了 JavaScript 语言的内部运作机制——帮助你充分利用 JavaScript 语言的表现力。通过全书归纳的 68 个行之有效的方法和大量具体实例,作者详细讲解了如何更有效地运用这门灵活且富有表现力的语言,以及如何规避其缺陷。你将学到如何选择正确的编程风格,管理一些超出意料的问题,以及成功使用 JavaScript 编程完成从数据结构到并发的方方面面。无论你写了多久的 JavaScript 代码,本书都将有助于增进你对这门强大的编程语言的理解,助你编写更可预测、更可靠且具维护性的程序。
關於作者:
David Herman,资深JavaScript技术专家,Ecma TC39委员会成员,负责JavaScript的标准化工作。他拥有格林内尔学院的计算机科学学士学位和美国东北大学的计算机科学硕士及博士学位,现任Mozilla研究院高级研究员。
目錄:
推荐序前言致谢关于作者Chapter 1: Accustoming Yourself to JavaScriptItem 1: Know Which JavaScript You Are UsingItem 2: Understand JavaScript’s Floating-Point NumbersItem 3: Beware of Implicit CoercionsItem 4: Prefer Primitives to Object WrappersItem 5: Avoid using == with Mixed TypesItem 6: Learn the Limits of Semicolon InsertionItem 7: Think of Strings As Sequences of 16-Bit Code UnitsChapter 2: Variable ScopeItem 8: Minimize Use of the Global ObjectItem 9: Always Declare Local VariablesItem 10: Avoid withItem 11: Get Comfortable with ClosuresItem 12: Understand Variable HoistingItem 13: Use Immediately Invoked Function Expressions to Create Local ScopesItem 14: Beware of Unportable Scoping of Named Function ExpressionsItem 15: Beware of Unportable Scoping of Block-Local Function DeclarationsItem 16: Avoid Creating Local Variables with evalItem 17: Prefer Indirect eval to Direct evalChapter 3: Working with FunctionsItem 18: Understand the Difference between Function, Method, and Constructor CallsItem 19: Get Comfortable Using Higher-Order FunctionsItem 20: Use call to Call Methods with a Custom ReceiverItem 21: Use apply to Call Functions with Different Numbers of ArgumentsItem 22: Use arguments to Create Variadic FunctionsItem 23: Never Modify the arguments ObjectItem 24: Use a Variable to Save a Reference to argumentsItem 25: Use bind to Extract Methods with a Fixed ReceiverItem 26: Use bind to Curry FunctionsItem 27: Prefer Closures to Strings for Encapsulating CodeItem 28: Avoid Relying on the toString Method of FunctionsItem 29: Avoid Nonstandard Stack Inspection PropertiesChapter 4: Objects and PrototypesItem 30: Understand the Difference between prototype, getPrototypeOf, and__proto__Item 31: Prefer Object.getPrototypeOf to __proto__Item 32: Never Modify __proto__Item 33: Make Your Constructors new-AgnosticItem 34: Store Methods on PrototypesItem 35: Use Closures to Store Private DataItem 36: Store Instance State Only on Instance ObjectsItem 37: Recognize the Implicit Binding of thisItem 38: Call Superclass Constructors from Subclass ConstructorsItem 39: Never Reuse Superclass Property NamesItem 40: Avoid Inheriting from Standard ClassesItem 41: Treat Prototypes As an Implementation DetailItem 42: Avoid Reckless Monkey-PatchingChapter 5: Arrays and DictionariesItem 43: Build Lightweight Dictionaries from Direct Instances of ObjectItem 44: Use null Prototypes to Prevent Prototype PollutionItem 45: Use hasOwnProperty to Protect Against Prototype PollutionItem 46: Prefer Arrays to Dictionaries for Ordered CollectionsItem 47: Never Add Enumerable Properties to Object.prototypeItem 48: Avoid Modifying an Object during EnumerationItem 49: Prefer for Loops to for...in Loops for Array IterationItem 50: Prefer Iteration Methods to LoopsItem 51: Reuse Generic Array Methods on Array-Like ObjectsItem 52: Prefer Array Literals to the Array ConstructorChapter 6: Library and API DesignItem 53: Maintain Consistent ConventionsItem 54: Treat undefined As “No Value”Item 55: Accept Options Objects for Keyword ArgumentsItem 56: Avoid Unnecessary StateItem 57: Use Structural Typing for Flexible InterfacesItem 58: Distinguish between Array and Array-LikeItem 59: Avoid Excessive CoercionItem 60: Support Method ChainingChapter 7: ConcurrencyItem 61: Don’t Block the Event Queue on IOItem 62: Use Nested or Named Callbacks for Asynchronous SequencingItem 63: Be Aware of Dropped ErrorsItem 64: Use Recursion for Asynchronous LoopsItem 65: Don’t Block the Event Queue on ComputationItem 66: Use a Counter to Perform Concurrent OperationsItem 67: Never Call Asynchronous Callbacks SynchronouslyItem 68: Use Promises for Cleaner Asynchronous LogicIndex
內容試閱:
推荐序众所周知,我在1995年5月用10天时间创建了JavaScript语言。迫于现实的压力和冲突管理的势在必行,我将JavaScript设计为“看起来像Java”、“对初学者来说极简单”、“在网景浏览器中几乎能控制它的一切”的编程语言。鉴于极具挑战性的要求和非常短的时间表,我的解决方案除了正确获得了两大特性(第一类函数、对象原型)之外,还将JavaScript设计得从一开始就极具延展性。我知道一些开发者不得不为最开始的几个版本“打补丁”来修正错误,这些先驱的方法比我使用内置库胡乱拼凑的方法要好。举例来说,虽然许多编程语言都限制了可变性,在运行时不能修改或扩展内置对象,或者标准库的名称绑定不能通过赋值被覆盖,但是JavaScript几乎允许完全改变每个对象。总的来说,我相信这是一个很好的设计决定。它明确了某些领域的挑战(如在浏览器的安全边界内,安全地混用可信和不可信的代码)。对于JavaScript来说,支持所谓的猴子补丁是很重要的。凭借它,开发者可以编辑标准对象来解决Bug和仿效“未来”的功能改造一些旧的浏览器(称为polyfill库的shim,在美式英语中称为spackle)。除了这些平凡的应用之外,JavaScript的可塑性鼓励用户沿着几个更富有创造性的方向形成和发展创新网络。这使得用户仿效其他编程语言,创建了许多工具包和框架库:基于Ruby的Prototype、基于Python的MochiKit、基于Java的Dojo及基于Smalltalk的TIBET。随后是jQuery库(“JavaScript的新浪潮”),2007年,我第一次看到它,我觉得自己似乎是一个后来者。它暴风雨般地引领着JavaScript的世界,异于其他编程语言,从旧的JavaScript库中学习,开辟了浏览器的“查询和做”(query and do)模型,从根本上简化了浏览器。这引领着JavaScript用户群及其创新网络,使JavaScript的风格自成一派。这种风格仍在仿效和简化其他的程序库,也促成了现代Web标准化的工作。在这一演变过程中,JavaScript保持了向后兼容,当然默认情况下,它是可变的。另外,在ECMAScript标准最新的版本中新增了一些方法来冻结对象和封闭对象的属性,以防止对象扩展和属性被覆盖。JavaScript的演进之旅远未结束。这就像生活的语言和生物系统一样,变化始终存在。在此之前,我无法预见一个单一的横扫其他程序库的“标准库”或编码风格。任何语言都是怪癖的,或者语言几乎都是受限地执行常见的上佳实践。JavaScript是一门怪癖的或者充满限制主义色彩的编程语言。因此,与大多数其他的编程语言相比,想要高效地使用JavaScript编程,开发人员必须学习和追求优秀的风格、正确的用法和上佳的实践。当考虑如何做到最高效,我相信避免过度编程和构建刚性或教条式的风格指南是至关重要的。本书以一种平衡的方式讲解JavaScript编程。它基于一些具体的实证和经验,而不迂回于刚性或过度的方法。我认为对于许多寻找在不牺牲表现力的前提下,还可以自由采用新思想和编程范式来编写高效JavaScript的人来说,本书是一位重要的助手和可信赖的向导。它也是一本备受关注、充满乐趣和拥有许多令人叹为观止的示例的读物。最后,自2006年以来,我有幸结识David Herman。那是我第一次以Mozilla代表的身份邀请他作为特邀专家在Ecma标准化机构工作。Dave深刻、谦逊的专家意见及他的热情让JavaScript在书中的每一页大放异彩。本书精彩绝伦!——Brendan Eich