Skip to content
This page has been auto-translated and may contain errors.View in English

什么是 JavaScript

docs.scrimba.com

打开一个网页并点击一个按钮打开菜单,在搜索框中输入内容时看到建议结果,或者在滚动时看到信息流加载更多帖子。这些都不是 HTML,也不是 CSS。这是 JavaScript:在浏览器内运行并使页面响应你的操作的语言。本章讲述的就是这种语言是什么,它在哪里运行,以及它如何与你已经知道的 HTML 和 CSS 配合。

一种让页面做事情的语言

JavaScript 是一种**编程语言**:一种编写指令的方式,让计算机逐步执行这些指令。HTML 描述页面上的内容,CSS 描述它的样子,而 JavaScript 描述发生的事情。它是响应性部分。

把网页想象成一座房子。HTML 是结构,是墙壁和房间。CSS 是油漆和家具。JavaScript 是电路和管道:是开关打开灯的布线,或水龙头产生水的机制。它使页面在人们与之交互时做出反应。

JavaScript 是网页的**行为**层。HTML 提供结构,CSS 提供表现;JavaScript 添加逻辑和交互性。它可以在页面加载后读取和更改页面,响应点击和按键等事件,跟踪状态,并与服务器通信以加载新数据。

与描述结果的 HTML 和 CSS 不同,JavaScript 是一种完整的编程语言:它有变量、条件、循环和函数。你不仅仅是声明你想要什么,你是在编写浏览器运行的步骤。这就是本手册所讲述的转变,从描述页面转向编程页面。

JavaScript 是一种高级、动态类型的编程语言(值有类型,但变量不会锁定在一个类型上,所以一个名字现在可以持有一个数字,稍后可以持有一个字符串)。在浏览器中,它是行为层:它响应事件操纵DOM(文档对象模型,浏览器从你的 HTML 构建的实时内存树),管理状态,并执行网络请求。

值得保留的框架是 HTML 和 CSS 是声明式的,而 JavaScript 是命令式的且图灵完全的:你表达计算,而不仅仅是期望的结果。这种能力就是为什么它承载了整个网络的交互性,也是为什么规律(HTML 和 CSS 几乎不需要)、命名、结构、错误处理,在逻辑进入页面的那一刻就成了你的责任。本手册的大部分内容讲的是如何运用这种能力而不制造只有你能读懂的混乱。

js
// HTML 给你一个按钮。JavaScript 使它做某事。
const button = document.querySelector(".menu-toggle");
button.addEventListener("click", openMenu);

你将在后面的章节中遇到所有这些内容。现在,注意这个形状:JavaScript 进入页面(document.querySelector),并响应用户所做的事情(addEventListener)。进入和响应是浏览器 JavaScript 做的大部分工作。

Juno一种让页面做事情的语言 HTML 是结构,CSS 是样式,JavaScript 是行为:是在有人使用页面时响应的部分。它是一种真正的编程语言,所以你编写浏览器逐步遵循的指令。这是你开始的转变:从描述页面到告诉它做什么。
Juno一种让页面做事情的语言 JavaScript 是行为层:它读取和更改页面,响应事件,并与服务器通信。不像 HTML 和 CSS,它是一种具有逻辑和状态的完整语言,所以你编程页面而不是声明它。在你的脑子里保持这份工作的清晰性使另外两个更容易安置。
Juno一种让页面做事情的语言 JavaScript 是命令式且图灵完全的,这就是为什么它承载了整个网络的交互性,以及为什么在逻辑出现时结构就成了你的工作。它是动态类型的,所以一个名字可以持有任何类型,类型检查在运行时发生。这里的大部分工艺就是运用这种能力而不写只有你能读的代码。

JavaScript 运行的地方

JavaScript 在浏览器内运行。每个浏览器,Chrome、Safari、Firefox,都有一个内置的**引擎**来读取你的 JavaScript 并运行它。这意味着没有什么要安装就能开始:如果你能打开网页,你就能运行 JavaScript。

你用 <script> 标签将 JavaScript 添加到页面,通常在闭合 </body> 标签之前。为了将你的代码保存在自己的文件中,用 src 属性指向该文件,就像图像标签指向图像一样。

尝试代码行的最快地方是浏览器控制台,这是开发者工具中的一个面板,你可以输入 JavaScript 并立即看到结果。

JavaScript 在**运行时**中运行:一个提供引擎来执行你的代码以及该代码可以使用的额外功能的环境。在浏览器中,运行时给你页面的 document、浏览器标签页的 window、网络请求的 fetch,还有更多。语言本身很小;你在浏览器中使用的大部分来自围绕它的运行时。用 <script> 标签和它的 src 属性加载外部脚本,添加 defer 以便浏览器在运行脚本前完成页面构建,这能让你避免一类"元素未找到"的错误。开发者工具中的控制台是一个你可以输入的实时运行时,它是你测试想法最快的地方。

JavaScript 由语言规范(ECMAScript)定义并由引擎(如 V8(Chrome、Node)或 JavaScriptCore(Safari))执行。引擎只是故事的一半:有用的能力来自**宿主环境**,嵌入引擎并向其暴露 API 的运行时。在浏览器中,该宿主是页面,提供 DOM、定时器、fetch、存储和事件;在像 Node 这样的服务器运行时中,它是操作系统,提供文件和套接字代替。

两个实际后果。首先,相同的语言在非常不同的地方运行,所以"这是 JavaScript 还是浏览器功能"是一个真正的区别:ArrayPromise 是语言,而 documentlocalStorage 是浏览器。其次,脚本如何加载影响行为:经典的 <script> 阻止解析,defer 在 DOM 构建后按顺序运行它,而 type="module" 默认延迟并给你 import/export 加上自己的作用域。知道你在使用哪一个解释了很多"为什么这在页面存在前运行了"的困惑。

JunoJavaScript 运行的地方 JavaScript 在浏览器中运行,浏览器已经有引擎来执行它,所以没有什么要安装。你用 <script> 标签将它添加到页面,尝试一行代码最快的地方是浏览器开发者工具中的控制台。打开它并输入一些东西,你不会破坏任何东西。
JunoJavaScript 运行的地方 浏览器给你一个运行时:引擎加上像 documentfetch 这样的额外功能。用 <script src> 加载你的代码,添加 defer 以便它在页面构建后运行。控制台是一个实时运行时来测试想法,它是你会得到的最快反馈。
JunoJavaScript 运行的地方 引擎运行语言(ECMAScript);宿主环境提供 API,这就是为什么 Array 是 JavaScript 但 document 是浏览器。脚本如何加载也很重要:经典脚本阻止解析,defer 按顺序在 DOM 之后运行,type="module" 延迟并添加导入作用域。该区别解释了大多数"它在页面存在前运行了"的错误。

你对 JavaScript 的第一个看法

这是一个很小的程序。你现在还不需要理解每个部分,后面的章节会讲到每一个,但你已经可以读懂它的形状:

js
let name = "李明";
console.log("你好 " + name); // 你好 李明

第一行在名字 name 下存储文本 "李明"。第二行在控制台中打印一条消息,将 "你好 " 和存储的名字连接在一起。console.log 是你在学习时要求 JavaScript 给你显示一个值的方式,你会不断使用它。

一个第一个程序,很小但完整:

js
let name = "李明";
let greeting = "你好 " + name;
console.log(greeting); // 你好 李明

三个想法已经在这里了:一个持有值的变量,一个结合值的表达式"你好 " + name),以及一个对结果做些什么的语句console.log)。几乎所有 JavaScript 都是这三样东西堆叠起来:给一些值命名,用它们计算,然后根据结果行动。console.log 打印到控制台,是你看到你的代码实际在做什么的默认工具。

最小的有用程序仍然展示了语言的核心循环:

js
const name = "李明";
const greeting = `你好 ${name}`;
console.log(greeting); // 你好 李明

注意一个工作开发者在这里反射地做的选择:const 而不是 let,因为绑定永远不会改变(表示意图并防止意外重新赋值),以及一个**模板字面量**(带有 ${...} 的反引号字符串)而不是 + 连接,因为它读起来更清楚,处理类型更可预测。这些都不需要让这一行运行,这正是重点:JavaScript 会很乐意接受松散版本,所以你代码的质量来自语言不强制的决定。本手册的大部分时间都用在这些决定上,从下一个 variables 开始。

Juno你对 JavaScript 的第一个看法 一个程序主要是这样的:存储一些值,结合它们,然后对结果做些什么。console.log 打印一个值以便你能看到它,它是你学习时的最好朋友。现在不用担心细节,你会在后面的章节中正确地遇到每个部分。
Juno你对 JavaScript 的第一个看法 大多数 JavaScript 是三样东西堆叠起来:持有值的变量、结合它们的表达式,以及对结果行动的语句。在任何片段中识别这三个使不熟悉的代码远没那么令人畏惧。将 console.log 保持在近处,它是你检查你的代码真正在做什么的方式。
Juno你对 JavaScript 的第一个看法 语言同样运行松散版本和仔细版本,所以质量来自它从不强制的选择:当绑定固定时 constlet,为了可读性用模板字面量对 +。这种自由是 JavaScript 的祝福和它的陷阱。接下来的章节很大程度上是关于如何很好地做出这些决定,从变量开始。

"现代 JavaScript" 是什么意思

你会听到人们谈论**现代 JavaScript**。JavaScript 自 1995 年以来就存在,它每年都会获得新功能,但旧代码持续工作,所以随着时间的推移,语言已经有了几种做同一件事的不同方式。

好消息是:你不需要历史。本手册教导当前、推荐的编写每样东西的方式。如果你看到使用 var 来创建变量的旧教程,那是旧风格;你会学习 letconst,这是开发者今天使用的。

"现代 JavaScript" 通常意味着自一个大型 2015 年更新以来的语言(称为**ES2015**,或 ES6)以及此后的每年更新。该更新添加了 letconst、箭头函数、模板字面量等,是每个当前浏览器都支持的基线。

这很重要,因为你会遇到两个时代的代码。较旧的材料使用 var、到处都是 function 表达式和字符串连接;当前代码使用 const/let、箭头函数和模板字面量。本手册始终教导现代风格,并仅命名更旧的形式以便你在野外识别它们。你不需要构建工具或配置来使用其中任何一个;它在浏览器中按原样运行。

JavaScript 标准化为ECMAScript,自 ES2015 以来规范每年发布(ES2016、ES2017 等),每个都添加一个小的、向后兼容的功能集。"现代 JavaScript" 是针对演变的语言编写的简写,const/let、箭头函数、模板字面量、解构、模块、async/await,而不是 2015 年前的习语。

这在实践中保持简单的原因是 JavaScript 对**向后兼容性**的近乎绝对的承诺:添加新语法,旧语法几乎从不破坏,所以十年前的脚本仍然运行。这就是为什么你可以只学习现代形式并安全地将 var 及其时代视为维护旧代码的只读知识。过去入侵的唯一地方是当你读别人的旧代码库时,本手册在这些旧形式出现时对其进行标记,以便它们不会绊倒你。下一章 variables 就从那里开始,用现代方式来命名和存储值。

Juno现代 JavaScript 是什么意思 JavaScript 很旧并且保持其旧代码的工作,所以有几种方式来做一些事情。你不需要历史:本手册每次都教导当前、推荐的方式。如果一个教程使用 var,那是旧风格,你会学习 letconst 代替。
Juno现代 JavaScript 是什么意思 现代 JavaScript 意味着自 2015 年更新以来的语言:constlet、箭头函数、模板字面量。你会遇到使用 var 和连接的旧代码,所以本手册教导现代风格,仅命名旧形式以便你识别它们。它都在浏览器中运行,没有构建步骤。
Juno现代 JavaScript 是什么意思 ECMAScript 每年发布并保持向后兼容,所以添加新语法,旧语法几乎从不破坏。这就是为什么你可以只学习现代形式并将 var 及其时代视为旧代码库的只读知识。针对演变的语言编写,让手册在传统形式出现时对其进行标记。

JavaScript 从这里去向何方

JavaScript 是一种大型语言,但它开始时很小:值、它们的名字,以及结合它们并对其进行操作的方式。一旦这些点击,本手册的其余部分向外构建:做出决定和重复工作,将代码组织到函数中,在数组对象中持有集合,然后用DOM本身进入页面来构建人们可以实际使用的东西。

下一章 variables 是真正工作开始的地方:如何存储值,letconst 之间的区别,以及整个其余语言所构建的小规则集。