欢迎来到 MDN 的 JavaScript 初学者课程!本节将在一定高度俯瞰 JavaScript,回答一些诸如“它是什么?”和“它能做什么?”的问题 。并使你熟悉 JavaScript 的用途。

预备知识: 计算机基础知识,初步理解 HTML 和 CSS 。
目标: 初步了解 JavaScript,包括一些概念、用途、嵌入网站的方法。

广义的定义

JavaScript 是一种脚本,一门编程语言,它可以在网页上实现复杂的功能,网页展现给你的不再是简单的静态信息,实时的内容更新,交互式的地图,2D/3D 动画,滚动播放的视频,等等。JavaScript 怎能缺席。它是标准 Web 技术蛋糕的第三层,其中 HTML CSS 我们已经在学习中心的其他部分进行了详细的讲解。

  • HTML是一种标记语言,用来结构化我们的网页内容并赋予内容含义,例如定义段落、标题和数据表,或在页面中嵌入图片和视频。
  • CSS 是一种样式规则语言,可将样式应用于 HTML 内容, 例如设置背景颜色和字体,在多个列中布局内容。
  • JavaScript 是一种脚本语言,可以用来创建动态更新的内容,控制多媒体,制作图像动画,还有很多。(好吧,虽然它不是万能的,但可以通过简短的代码来实现神奇的功能。)

这三层依次建立,秩序井然。举一个文本标签的简单示例。首先用 HTML 将文本标记起来,从而赋予它结构和目的:

<p>玩家1:小明</p>

玩家1:小明

然后我们可以为它加一点 CSS 让它更好看:

p {
  font-family: sans-serif, '黑体';
  letter-spacing: 1px;
  text-transform: uppercase;
  text-align: center;
  border: 2px solid rgba(0,0,200,0.6);
  background: rgba(0,0,200,0.3);
  color: rgba(0,0,200,0.6);
  box-shadow: 1px 1px 2px rgba(0,0,200,0.4);
  border-radius: 10px;
  padding: 3px 10px;
  display: inline-block;
  cursor:pointer;
}

最后,我们可以再加上一些 JavaScript 来实现动态行为:

var para = document.querySelector('p');

para.addEventListener('click', updateName);

function updateName() {
  var name = prompt('输入一个新的名字:');
  para.textContent = '玩家1:' + name;
}

尝试点击最后一个版本的文本标签,观察会发生什么(同时你可以在 GitHub 上找到这个 demo。查看 源代码在线运行。)

JavaScript 还能做更多。让我们来仔细探索。

到底可以做什么?

JavaScript 语言的核心包含一些普遍的编程特性,以让你可以做到如下的事情:

  • 在变量中储存有用的值。比如上文的示例中,我们请求客户输入一个新名字,然后将其储存到 name 变量中。
  • 操作一段文本(在编程中称为“字符串”(string))。上文的示例中,我们取字符串 "玩家1:",然后把它和 name 变量连结起来,创造出完整的文本标签,比如:'玩家1:小明"。
  • 运行代码以响应网页中发生的特定事件。上文的示例中,我们用一个 click 事件来检测按钮什么时候被点击,然后运行代码更新文本标签。
  • 以及更多!

JavaScript 语言核心之上所构建的功能更令人兴奋。应用程序接口(Application Programming InterfacesAPI))将为你的代码提供额外的超能力。

API 是已经建立好的一套代码组件,可以让开发者实现原本很难甚至无法实现的程序。就像现成的家具套件之于家居建设,用一些已经切好的木板组装一个书柜,显然比自己设计,寻找合适的木材,裁切至合适的尺寸和形状,找到正确尺寸的螺钉,再组装成书柜要简单得多。

API 通常分为两类。

浏览器 API 内建于 web 浏览器中,它们可以使周边计算环境的数据暴露出来,还可以做实用的复杂工作。例如:

: 上述很多演示都不能在旧浏览器中运行。推荐你在测试代码时使用诸如 Firefox, Chrome, Edge 或者 Opera 等现代浏览器。当代码即将交付生产环境时(也就是真实的客户即将使用真实的代码时),你还需要深入考虑 跨平台测试

第三方 API 并没有默认嵌入浏览器中,一般要从网上取得它们的代码和信息。比如:

  • Twitter API 可以用来在你的网站上展示最新推文之类。
  • Google Maps API 可以在你的网站嵌入定制的地图等等。
  • 当然它们是打不开的:) 

:这些 API 较为高级,我们的课程中不会涉及它们,更多信息请参考: 客户端 web API 模块.

先稳住!你看到的只是冰山一角。你不可能学一天 JavaScript 就能构建下一个微博、高德地图或者微信。敬请「牢记初心,砥砺前行」。

JavaScript 在页面上做了什么?

现在我们实实在在的学习一些代码,与此同时,探索 JavaScript 运行时背后发生的事情。

让我们简单回顾一下,浏览器在读取一个网页时都发生什么(CSS 如何工作 一文中首次谈及)。浏览器在读取一个网页时,代码(HTML, CSS 和 JavaScript)将在一个运行环境(浏览器标签)中得到执行。就像一间工厂,将原材料(代码)加工为一件产品(网页)。

在 HTML 和 CSS 集合组装成一个网页后,浏览器的 JavaScript 引擎将执行 JavaScript 代码。这保证了当 JavaScript 开始运行之前,网页的结构和样式已经就位。

这样很好,因为通过 DOM API(见上文)动态修改 HTML 和 CSS 来更新 UI 正是 JavaScript 最普遍的用处所在。如果 JavaScript 在 HTML 和 CSS 就位之前加载运行,就会引发错误。

浏览器安全

每个浏览器标签页就是其自身用来运行代码的独立容器(这些容器用专业术语称为“运行环境”)。大多数情况下,每个标签页中的代码完全独立运行,而且一个标签页中的代码不能直接影响另一个标签页(或者另一个网站)中的代码。这是一个好的安全措施,如果不这样,黑客就可以从其他网站盗取信息,等等。

注:可以用安全的方式在不同网站/标签页中传送代码和数据,但这些技术较为高级,本课程不会涉及。

JavaScript 运行次序

当浏览器执行到一段 JavaScript 代码时,通常会按从上往下的顺序执行这段代码。这意味着你需要注意代码的顺序。比如,我们回到第一个例子中的 JavaScript 代码:

var para = document.querySelector('p');

para.addEventListener('click', updateName);

function updateName() {
  var name = prompt('输入一个新的名字:');
  para.textContent = '玩家1:' + name;
}

这里我们选定一个文本段落(第 1 行),然后给它附上一个事件监听器(第 3 行),使得在它被点击时,updateName() 代码块 (5 – 8 行)会运行。updateName() (这类可以重复使用的代码块称为“函数”)请求一个新的名字,然后把这个名字插入到段落中以更新显示。

如果你互换了代码里最初两行的顺序,会出现问题。浏览器开发者控制台将返回一个错误: TypeError: para is undefined。这意味着 para 对象还不存在,所以我们不能为它增添一个事件监听器。

注:这是一个很常见的错误,在引用对象之前必须确保该对象已经存在。

解释代码 vs 编译代码

作为程序员,你或许听说过这两个术语:解释(interpret)编译(compile)。在解释型语言中,代码自上而下运行,且实时返回运行结果。代码在执行前,无需由浏览器将其转化为其他形式。

与此同时,编译型语言代码能够运行之前需要先转化(编译)成另一种形式。比如 C/C++ 先被编译成汇编语言,然后才能由计算机运行。

JavaScript 是轻量级解释型语言。两种方式各有优势,这个问题我们暂且不谈。

服务器端代码 vs 客户端代码

你或许还听说过服务器端(server-side)和 客户端(client-side)代码这两个术语,尤其是在web开发时。客户端代码是在用户的电脑上运行的代码,在浏览一个网页时,它的客户端代码就会被下载,然后由浏览器来运行并展示。这就是客户端 JavaScript

而服务器端代码在服务器上运行,浏览器将结果下载并展示出来。流行的服务器端 web 语言包括:PHP、Python、Ruby、ASP.NET 以及 JavaScript!JavaScript 也可用作服务器端语言,比如现在流行的 Node.js 环境,你可以在我们的 动态网页 - 服务器端编程 主题中找到更多关于服务器端 JavaScript 的知识。

动态代码 vs 静态代码

动态”一词既能描述客户端 JavaScript,又能描述服务器端语言。是指通过按需生成新内容来更新 web 页面 / 应用,使得不同环境下显示不同内容。服务器端代码会在服务器上动态生成新内容,例如从数据库中提取信息。而客户端 JavaScript 则在用户端浏览器中动态生成新内容,比如说创建一个新的 HTML 表格,用从服务器请求到的数据填充,然后在网页中向用户展示这个表格。两种情况的意义略有不同,但又有所关联,且两者(服务器端和客户端)经常协同作战。

没有动态更新内容的网页叫做“静态”页面所显示的内容不会改变。

怎样向页面添加 JavaScript?

可以像添加 CSS 那样将 JavaScript 添加到 HTML 页面中。CSS 使用 <link> 元素链接外部样式表,使用 <style> 元素向 HTML 嵌入内部样式表,JavaScript 这里只需一个元素——<script>。我们来看看它是怎么工作的。

内部的 JavaScript

  1. 首先,下载示例文件 apply-javascript.html。放在一个好记的文件夹里。
  2. 分别在浏览器和文本编辑器中打开这个文件。你会看到这个 HTML 文件创建了一个简单的网页,其中有一个可点击按钮。
  3. 然后转到文本编辑器,在 </body> 标签前插入以下代码:
    <script>
    
      // 在此编写 JavaScript 代码
    
    </script>
  4. 下面,在 <script> 元素中添加一些 JavaScript 代码,这个页面就能做一些更有趣的事。在“/ /在此编写 JavaScript 代码”一行下方添加以下代码:
    document.addEventListener("DOMContentLoaded", function() {
      function createParagraph() {
        var para = document.createElement('p');
        para.textContent = '你点击了这个按钮!';
        document.body.appendChild(para);
      }
    
      var buttons = document.querySelectorAll('button');
    
      for(var i = 0; i < buttons.length ; i++) {
        buttons[i].addEventListener('click', createParagraph);
      }
    });
  5. 保存文件并刷新浏览器,然后你会发现,点击按钮文档下方将会添加一个新段落。

: 如果示例不能正常工作,请依次检查所有步骤,并保证没有纰漏。原始文件是否以 .html 为扩展名保存到本地了?</body> 标签前是否添加了 <script> 元素?JavaScript 代码输入是否正确 ? JavaScript 是区分大小写的,而且非常精确,所以你需要准确无误地输入所示的句法,否则可能会出错。

: 你可以在 GitHub 上查看此版本  apply-internal.html (也可在线查看)。

外部的 JavaScript

这很不错,但是能不能把 JavaScript 代码放置在一个外部文件中呢?现在我们来研究一下。

  1. 首先,在刚才的 HTML 文件所在的目录下创建一个名为 script.js 的新文件。请确保扩展名为 .js,只有这样才能被识别为 JavaScript 代码。
  2. <script> 元素替换为:
    <script src="script.js"></script>
  3. script.js 文件中,添加下面的脚本:
    function createParagraph() {
      var para = document.createElement('p');
      para.textContent = '你点击了这个按钮!';
      document.body.appendChild(para);
    }
    
    var buttons = document.querySelectorAll('button');
    
    for(let i = 0; i < buttons.length ; i++) {
      buttons[i].addEventListener('click', createParagraph);
    } 
  4. 保存并刷新浏览器,你会发现二者完全一样。但是现在我们把 JavaScript 写进了一个外部文件。这样做一般会使代码更加有序,更易于复用,且没有了脚本的混合,HTML 也会更加易读,因此这是个好的习惯。

注:你可以在 GitHub 上查看这个版本 apply-external.html 以及 script.js (也可在线查看).

内联 JavaScript 处理器

注意,有时候你会遇到在 HTML 中存在着一丝真实的 JavaScript 代码。它或许看上去像这样:

function createParagraph() {
  var para = document.createElement('p');
  para.textContent = '你点击了这个按钮!';
  document.body.appendChild(para);
}
<button onclick="createParagraph()">点我呀</button>

你可以在下面尝试这个版本的 demo。

这个 demo 与之前的两个功能完全一致,只是在 <button> 元素中包含了一个内联的 onclick 处理器,使得函数在按钮被按下时运行。

然而请不要这样做。 这将使 JavaScript 污染到 HTML,而且效率低下。对于每个需要应用 JavaScript 的按钮,你都得手动添加 onclick="createParagraph()" 属性。

可以使用纯 JavaScript 结构来通过一个指令选取所有按钮。下文的这段代码即实现了这一目的:

var buttons = document.querySelectorAll('button');

for(var i = 0; i < buttons.length ; i++) {
  buttons[i].addEventListener('click', createParagraph);
}

这样写乍看去比 onclick 属性要长一些,但是这样写会对页面上所有按钮生效,无论多少个,或添加或删除,完全无需修改 JavaScript 代码。

:请尝试创建你自己的 apply-javascript.html 版本并添加更多按钮。重新加载时,你将发现按下任一按钮时都会创建一个段落。很高效吧。

注释

就像 HTML 和 CSS,JavaScript 代码中也可以添加注释,浏览器会忽略它们,注释只是为你的同事(还有你,如果半年后再看自己写的代码你会说,这是什么垃圾玩意。)提供关于代码如何工作的指引。注释非常有用,而且你应该经常使用它们,尤其在大型应用中。注释分为两类:

  • 在双斜杠后添加单行注释,比如:
    // 我是一条注释
  • 在 /* 和 */ 之间添加多行注释,比如:
    /*
      我也是
      一条注释
    */

比如说,我们可以这样为上一个 demo 添加注释:

// 函数:创建一个新的段落并添加至 HTML body 底部。
function createParagraph() {
  var para = document.createElement('p');
  para.textContent = '你点了这个按钮!';
  document.body.appendChild(para);
}

/*
  1. 取得页面上所有按钮的引用并将它们置于一个数组中。
  2. 通过一个循环为每个按钮添加一个点击事件的监听器。
  当按钮被点击时,调用 createParagraph() 函数。
*/

var buttons = document.querySelectorAll('button');

for (var i = 0; i < buttons.length; i++) {
  buttons[i].addEventListener('click', createParagraph);
}

总结

恭喜你,你在 JavaScript 世界迈出了第一步。我们仅仅从理论开始,让你熟悉为什么要使用 JavaScript,以及用它能做什么事情。过程中你看到了一些代码示例并且学到了 JavaScript 是如何与你网站中的其他代码适配的,等等。

现在 JavaScript 或许还有些令人生畏,但不用担心。在课程中我们会逐步地引导你。下一节我们将 全力投入实战,让你专注其中并建立你自己版本的 JavaScript 示例。

 

本章目录

 

文档标签和贡献者

最后编辑者: HowieZhao,