菜单

快速入门

相关源文件

目的与范围

本文档涵盖了“你不知道的 JavaScript yet”(YDKJSY)系列第一本书中介绍的 JavaScript 基础知识。“入门”一书是 JavaScript 的入口点,为深入研究后续书籍中更专业的主题之前,提供了理解语言核心机制的基础。虽然它介绍了基本概念,但它并非旨在作为初学者的编程入门教程——相反,它假设你已经熟悉 JavaScript 的基本知识,并旨在加深你对语言底层工作原理的理解。

有关闭包和作用域等更高级的主题,请参阅作用域与闭包;有关面向对象模式,请参阅对象与类;有关 JavaScript 的类型系统,请参阅类型与语法

来源:get-started/ch1.md10-20 get-started/ch4.md1-10

书籍组织结构

“入门”分为四个主要章节加上附录,每一章都建立在前一章的基础上,为理解 JavaScript 奠定全面的基础。

来源:get-started/toc.md1-45 get-started/README.md1-20 get-started/ch1.md4-20

JavaScript 的三大支柱

“入门”一书的核心概念是,JavaScript 构建在三个基本支柱之上,这三个支柱在系列的后续书籍中将得到详细探讨。

来源:get-started/ch4.md12-67 get-started/ch1.md16-18

第一章:什么是 JavaScript?

本章通过解决常见的误解和解释其核心本质,为理解 JavaScript 奠定了基础。

JavaScript 的名称与演变

“JavaScript”这个名字在很大程度上是一个营销的产物——该语言最初的代码名称是 Mocha,然后品牌化为 LiveScript,最后改名为 JavaScript 以吸引 Java 程序员。尽管名称相似,JavaScript 与 Java 完全不同。根据规范,该语言的官方名称是 ECMAScript(有 ES2019 等年度版本)。

来源:get-started/ch1.md22-50

语言规范

JavaScript 由 TC39 正式规范,该委员会通过 ECMA International 管理 ECMAScript 规范。该委员会由浏览器制造商、设备制造商和其他利益相关者的代表组成。新功能在纳入语言规范之前,需要经历一个五阶段的过程(0-4)。

阶段描述
0Strawperson(草案):由 TC39 成员倡导的初始想法
1Proposal(提案):包含 API 示例的正式提案
2Draft(草稿):初始规范文本
3Candidate(候选):完整规范,有实施反馈
4Finished(完成):准备纳入标准

来源:get-started/ch1.md55-78

JavaScript 环境

TC39/ECMA 仅指定了一个 JavaScript 语言,但它可以在各种环境中运行。

环境备注
浏览器主要的浏览器环境,每个环境都有自己的 JS 引擎(Chrome 使用 V8,Firefox 使用 SpiderMonkey 等)。
Node.js使用 Chrome V8 引擎的服务器端 JS 环境
其他嵌入式环境物联网设备、机器人等。

某些环境会添加看起来像 JavaScript 的 API(例如 alert()console.log()),但它们本身并不是 JS 规范的一部分。

来源:get-started/ch1.md85-128

JavaScript 的范式

JavaScript 是一种多范式语言,允许开发人员以多种风格编写代码。

  1. 过程式:将代码组织成自上而下、线性的顺序。
  2. 面向对象:使用类将逻辑和数据收集在一起。
  3. 函数式:将函数视为头等值并组合它们。

这种灵活性意味着您可以为手头的任务选择适当的范式——有时甚至可以在同一程序中混合范式。

来源:get-started/ch1.md156-176

向后兼容与向前兼容

JavaScript 的基本原则之一是向后兼容。一旦某个东西成为有效的 JavaScript,该语言的未来版本将不会破坏该代码。这确保了多年前编写的代码今天仍然可以运行。

JavaScript 不是向前兼容的,这意味着新功能无法在旧的 JS 引擎中使用。为了解决这个问题,开发人员使用了

  1. 转译(Transpiling):使用 Babel 等工具将较新的语法转换为等效的旧语法。
  2. 填充(Polyfilling):添加缺失的 API 方法的定义,以便旧环境可以使用新方法。

来源:get-started/ch1.md178-311

JavaScript:解释型还是编译型?

JavaScript 在执行前会被解析和编译,而不是简单地逐行解释。

此编译步骤允许在执行前进行早期错误检测和性能优化,这使得 JavaScript 更恰当地被归类为编译型语言,而不是纯粹的解释型语言。

来源:get-started/ch1.md313-381

第二章:JavaScript 概览

本章通过 tour 的方式介绍 JavaScript 的关键语法和行为,为更深入的探索打下基础。

程序、文件和模块

在 JavaScript 中,每个独立的文件都被视为一个单独的程序。文件可以通过以下方式相互交互:

  1. 全局作用域共享:多个文件在全局命名空间中混合。
  2. 模块:ES6 模块的 import/export 创建了更受控的依赖关系。

理解这种分离对于错误处理很重要,因为一个文件中的错误不一定会阻止其他文件中的代码执行。

来源:get-started/ch2.md18-38

值和类型

JavaScript 有两类广泛的值:

  1. 原始类型(Primitives):直接、简单的值。

    • 字符串(String):"hello", 'world', `template ${value}`
    • 数字(Number):42, 3.14
    • 布尔值(Boolean):true, false
    • 未定义(Undefined):undefined
    • 空值(Null):null
    • Symbol:Symbol("description")
    • BigInt:42n
  2. 对象(Objects):属性的集合。

    • 普通对象:{ key: value }
    • 数组(Arrays):[1, 2, 3]
    • 函数(Functions):function() {}
    • 专用对象(Date、RegExp 等)

typeof 操作符有助于确定值的类型,但有一些怪癖(例如,typeof null 返回"object")。

来源:get-started/ch2.md40-184

变量与声明

JavaScript 提供了多种声明变量的方式,每种都有不同的行为。

声明范围重新赋值提升(Hoisting)行为
var函数作用域允许声明被提升,初始化为undefined
let块作用域允许声明被提升,但未初始化(临时死区 TDZ)。
const块作用域不允许声明被提升,但未初始化(临时死区 TDZ)。

来源:get-started/ch2.md185-295

函数

JavaScript 中的函数是头等值,可以被赋值、作为参数传递以及从其他函数返回。它们可以通过多种方式定义:

  1. 函数声明:

  2. 函数表达式:

  3. 箭头函数(ES6+)

  4. 对象方法:

这本书强调了理解函数如何工作的重要性,因为它们是 JavaScript 设计的核心。

来源:get-started/ch2.md296-376

比较

JavaScript 同时包含严格相等(===)和宽松相等(==)比较。

  1. 严格相等(===:在不进行转换的情况下比较值和类型。

    • 例外:NaN !== NaN0 === -0
    • 对于对象,比较的是引用,而不是内容(身份相等)。
  2. 宽松相等(==:允许在比较前进行类型转换。

    • 倾向于转换为数字:42 == "42"true
    • 经常被误解,但遵循特定的强制转换规则。
  3. 关系运算符<, >, <=, >=

    • 也执行类型转换(通常转换为数字)。
    • 当两个值都是字符串时,按字母顺序比较字符串。

理解强制转换对于掌握 JavaScript 比较至关重要。

来源:get-started/ch2.md378-514

组织:类与模块

JavaScript 提供了两种主要的组织代码的模式:

JavaScript 支持类导向设计,使用class语法(ES6+),允许传统 OOP 模式。

类还支持使用extends关键字和super访问父类来进行继承。

模块

JavaScript 模块封装数据和行为。

  1. ES 模块(JavaScript 原生支持)。

  2. CommonJS 模块(Node.js)。

来源:get-started/ch2.md516-636

第三章:深入 JavaScript 的根源

本章探讨了 JavaScript 中更基础的方面,这些方面是几乎所有 JavaScript 代码的基础。

迭代

JavaScript 的迭代协议标准化了我们如何一次从数据源中消耗一个项目。

可以通过以下方式消耗迭代:

  1. for...of 循环for (let value of iterable) { /* ... */ }
  2. 展开运算符[...iterable]doSomething(...iterable)

内置可迭代对象包括数组、字符串、Map 和 Set。每个对象默认提供对其值的迭代,但也可以通过 entries()keys()values() 方法公开专门的迭代器。

来源:get-started/ch3.md12-169

闭包

闭包是 JavaScript 中最强大、最重要的特性之一。

闭包是指一个函数记住并继续访问其范围之外的变量,即使该函数在不同的范围中执行。

在此示例中,内部的 increaseCount() 函数“闭合”了其外部范围中的 countstep 变量,在 counter() 执行完毕后仍然可以访问它们。

闭包最常用于:

  • 回调和事件处理程序
  • 函数工厂
  • 模块模式

来源:get-started/ch3.md170-266

this 关键字

JavaScript 中的 this 关键字指向一个执行上下文,该上下文在函数被调用时动态确定。

与许多其他语言不同,JavaScript 中的 this 不是词法作用域——它取决于函数的调用方式,而不是定义它的位置。这种动态特性使得函数能够灵活地与不同的数据对象重用。

来源:get-started/ch3.md268-340

原型

JavaScript 的原型系统允许对象通过称为原型链的链接将行为委托给其他对象。

当在对象上找不到属性时,JavaScript 会沿着原型链向上查找,直到找到该属性或到达链的末端。

创建具有原型链接的对象

这个原型委托系统构成了 JavaScript 面向对象模式的基础,包括其 class 语法。

来源:get-started/ch3.md342-469

第四章:全局图景

本章将 JavaScript 置于上下文中,围绕三个核心支柱组织知识,并提供如何继续学习的指导。

JavaScript 的三大支柱详解

支柱 1:作用域和闭包

作用域定义了 JavaScript 中变量的组织和访问方式。

  • 词法作用域在解析/编译时确定。
  • 函数作用域与块作用域
  • 变量提升和 TDZ(暂时死区)
  • 闭包使函数能够记住其原始作用域。

这一支柱对于理解变量如何工作以及如何有效地构建代码至关重要。

支柱 2:原型

原型系统支持对象链接和行为委托。

  • 对象可以通过原型链接委托行为。
  • 原型链提供属性/方法查找。
  • this 关键字在方法中支持动态上下文。
  • JavaScript 中的类是建立在原型系统之上的。

理解原型可以使开发人员除了类之外,还能有多种组织代码的方法。

支柱 3:类型和强制转换

JavaScript 的类型系统包括:

  • 原始类型(字符串、数字、布尔值等)
  • 对象和引用
  • 类型之间的类型转换(强制类型转换)
  • 相等性比较(严格 vs. 宽松)

这一支柱通常是最容易被误解的,但对于编写有效的 JavaScript 代码至关重要。

来源:get-started/ch4.md12-67

学习路径和书籍系列结构

本书最后建议了 YDKJSY 系列的学习路径。

建议的阅读顺序是:

  1. 入门(本书)——JavaScript 基础
  2. 作用域与闭包——第一支柱深入
  3. 对象与类——第二支柱深入
  4. 类型与语法——第三支柱深入
  5. 同步与异步——JavaScript 中的流程控制
  6. ES.Next 及以后——即将推出的功能和增强

虽然第 2、3、4 本书可以按任何顺序阅读,但都应该学习以全面理解 JavaScript。

来源:get-started/ch4.md100-128

附录

本书包含两个附录,提供附加材料。

附录 A:进一步探索

涵盖更多高级主题,这些主题建立在主要章节的基础上。

  1. 值与引用:理解原始值和对象值是如何赋值和传递的。
  2. 函数形式:JavaScript 中定义函数的多种方式。
  3. 强制条件比较:条件语句如何处理类型转换。
  4. 原型类:使用原型系统实现的 ES6 之前的类模式。

来源:get-started/apA.md1-327

附录 B:实践,实践,再实践!

包含带有解决方案的实践编码练习,以巩固学习。

  1. 练习比较:在日程时间计算中处理强制类型转换。
  2. 练习闭包:创建一个具有部分应用的 range 函数。
  3. 练习原型:构建一个带有原型委托的老虎机。

这些练习将主要章节中的概念应用于实践,以通过动手实践来巩固理解。

来源:get-started/apB.md1-337

学习方法

本书强调一种特定的 JavaScript 学习方法:

  1. 从容学习:不要急于学习内容;慢慢消化。
  2. 规律练习:将概念应用于实际代码。
  3. 质疑一切:为编写的每一行代码问“为什么”。
  4. 学习所有部分:不要只关注“好部分”,要理解所有内容是如何工作的。
  5. 顺势而为:与 JavaScript 的设计模式合作,而不是对抗。

目标不仅仅是让代码运行,而是理解代码如何以及为何运行,从而编写出更易于维护和更有效的 JavaScript 程序。

来源:get-started/ch1.mdpreface.md67-84