From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- .../first_steps/a_first_splash/index.html | 744 +++++++++++++++++++++ .../learn/javascript/first_steps/arrays/index.html | 522 +++++++++++++++ .../zh-cn/learn/javascript/first_steps/index.html | 57 ++ .../learn/javascript/first_steps/math/index.html | 429 ++++++++++++ .../first_steps/silly_story_generator/index.html | 239 +++++++ .../javascript/first_steps/strings/index.html | 288 ++++++++ .../test_your_skills_colon__variables/index.html | 78 +++ .../first_steps/useful_string_methods/index.html | 474 +++++++++++++ .../javascript/first_steps/variables/index.html | 431 ++++++++++++ .../first_steps/what_is_javascript/index.html | 501 ++++++++++++++ .../first_steps/what_went_wrong/index.html | 284 ++++++++ 11 files changed, 4047 insertions(+) create mode 100644 files/zh-cn/learn/javascript/first_steps/a_first_splash/index.html create mode 100644 files/zh-cn/learn/javascript/first_steps/arrays/index.html create mode 100644 files/zh-cn/learn/javascript/first_steps/index.html create mode 100644 files/zh-cn/learn/javascript/first_steps/math/index.html create mode 100644 files/zh-cn/learn/javascript/first_steps/silly_story_generator/index.html create mode 100644 files/zh-cn/learn/javascript/first_steps/strings/index.html create mode 100644 files/zh-cn/learn/javascript/first_steps/test_your_skills_colon__variables/index.html create mode 100644 files/zh-cn/learn/javascript/first_steps/useful_string_methods/index.html create mode 100644 files/zh-cn/learn/javascript/first_steps/variables/index.html create mode 100644 files/zh-cn/learn/javascript/first_steps/what_is_javascript/index.html create mode 100644 files/zh-cn/learn/javascript/first_steps/what_went_wrong/index.html (limited to 'files/zh-cn/learn/javascript/first_steps') diff --git a/files/zh-cn/learn/javascript/first_steps/a_first_splash/index.html b/files/zh-cn/learn/javascript/first_steps/a_first_splash/index.html new file mode 100644 index 0000000000..d54ec0c4ed --- /dev/null +++ b/files/zh-cn/learn/javascript/first_steps/a_first_splash/index.html @@ -0,0 +1,744 @@ +--- +title: JavaScript 初体验 +slug: Learn/JavaScript/First_steps/A_first_splash +tags: + - JavaScript + - 事件 + - 函数 + - 初学者 + - 变量 + - 学习 + - 操作符 + - 教程 + - 添加 +translation_of: Learn/JavaScript/First_steps/A_first_splash +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/What_is_JavaScript", "Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps")}}
+ +

现在,你已经学到了一些 JavaScript 的理论知识,以及用 JavaScript 能够做些什么。下面我们会提供一个讲解 Javascript 基本特性的 Crash Course,课程是一个全面的实践性项目——循序渐进地构建一个简易版“猜数字”游戏。

+ + + + + + + + + + + + +
预备知识:计算机基础知识,初步理解HTML和CSS,了解JavaScript。
目标:获得编写JavaScript的初体验,初步了解编写JavaScript时会涉及哪些内容。
+ +

我们并不要求你立刻完整理解所有代码,当前只是概括地介绍一些抽象的概念,并且让你对JavaScript(以及其他编程语言)工作原理有一定的认知。所有具体特性将在后续文章中详细介绍。

+ +
+

注: 可以看到,JavaScript 中许多代码特性和其他编程语言是一致的( 函数、循环,等等)。尽管代码语法不尽相同,但概念基本类似。

+
+ +

像程序员一样思考

+ +

学习编程,语法本身并不难,真正困难的是如何应用它来解决现实世界的问题。 你要开始像程序员那样思考。一般来讲,这种思考包括了解你程序运行的目的,为达到该目的应选定的代码类型,以及如何使这些代码协同运行。

+ +

为达成这一点,我们需要努力编程,获取语法经验,注重实践,再加一点创造力,几项缺一不可。代码写的越多,就会完成的越优秀。虽然我们不能保证你在5分钟内拥有“程序员大脑”,但是整个课程中你将得到大量机会来训练程序员思维。

+ +

请牢记这一点,然后开始观察本文的示例,体会一下将其分解为可操作任务的大体过程。

+ +

示例——猜数字游戏

+ +

本文将向你演示如何构建下面的小游戏:

+ + + +

{{ EmbedLiveSample('Top_hidden_code', '100%', 320, "", "", "hide-codepen-jsfiddle") }}

+ +

先玩上几盘,在继续之前先熟悉一下这个游戏。

+ +

假设你的老板给你布置了以下游戏设计任务要求:

+ +
+

我想让你开发一个猜数字游戏。游戏应随机选择一个 100 以内的自然数, 然后邀请玩家在 10 轮以内猜出这个数字。每轮后都应告知玩家的答案正确与否,如果出错了,则告诉他数字是低了还是高了。并且应显示出玩家前一轮所猜的数字。一旦玩家猜对,或者用尽所有机会,游戏将结束。游戏结束后,可以让玩家选择再次开始。

+
+ +

看到这个要求,首先我们要做的是将其分解成简单的可操作的任务,尽可能从程序员的思维去思考:

+ +
    +
  1. 随机生成一个 100 以内的自然数。
  2. +
  3. 记录玩家当前的轮数。从 1 开始。
  4. +
  5. 为玩家提供一种猜测数字的方法。
  6. +
  7. 一旦有结果提交,先将其记录下来,以便用户可以看到他们先前的猜测。
  8. +
  9. 然后检查它是否正确。
  10. +
  11. 如果正确: +
      +
    1. 显示祝贺消息。
    2. +
    3. 阻止玩家继续猜测(这会使游戏混乱)。
    4. +
    5. 显示控件允许玩家重新开始游戏。
    6. +
    +
  12. +
  13. 如果出错,并且玩家有剩余轮次: +
      +
    1. 告诉玩家他们错了。
    2. +
    3. 允许他们输入另一个猜测。
    4. +
    5. 轮数加 1。
    6. +
    +
  14. +
  15. 如果出错,并且玩家没有剩余轮次: +
      +
    1. 告诉玩家游戏结束。
    2. +
    3. 阻止玩家继续猜测(这会使游戏混乱)。
    4. +
    5. 显示控件允许玩家重新开始游戏。
    6. +
    +
  16. +
  17. 一旦游戏重启,确保游戏的逻辑和UI完全重置,然后返回步骤1。
  18. +
+ +

让我们继续,看看我们如何将这些步骤转换为代码,构建这个示例,从而探索 JavaScript 的功能。

+ +

初始设置

+ +

本教程开始前,请将 number-guessing-game-start.html 文件保存下来。同时在文本编辑器和Web浏览器中将其打开,可以看到一个简单的标题,一段游戏说明,和一个用于输入猜测的表单,此时表单不会执行任何操作。

+ +

我们将在 HTML 底部的 {{htmlelement("script")}} 元素中添加新的代码:

+ +
<script>
+
+   // 开始编写 JavaScript 代码
+
+</script>
+
+ +

添加变量以保存数据

+ +

让我们开始吧。首先,在  {{htmlelement("script")}}  元素中添加以下代码:

+ +
let randomNumber = Math.floor(Math.random() * 100) + 1;
+
+const guesses = document.querySelector('.guesses');
+const lastResult = document.querySelector('.lastResult');
+const lowOrHi = document.querySelector('.lowOrHi');
+
+const guessSubmit = document.querySelector('.guessSubmit');
+const guessField = document.querySelector('.guessField');
+
+let guessCount = 1;
+let resetButton;
+ +

这段代码设置了存储数据的变量和常量以供程序使用。变量本质上是值(例如数字或字符串)的容器。 你可以使用关键字 let (旧代码中使用 var)和一个名字来创建变量(请参阅 let 和 var 之间的区别)。常量用于存储不希望更改的数据,用关键字 const 创建,本例中用常量来保存对界面元素的引用。界面元素的文字可能会改变,但引用是不变的。

+ +

可以使用等号(=)和一个值来为变量赋值。

+ +

在我们的示例中:

+ + + +
+

: 稍后将讲解更多关于变量/常量的信息。参见下节

+
+ +

函数(Function)

+ +

下面,在之前的代码中添加以下内容:

+ +
function checkGuess() {
+  alert('我是一个占位符');
+}
+ +
+
函数是可复用的代码块,可以一次编写,反复运行,从而节省了大量的重复代码。它们真的很有用。定义函数的方法很多,但现在我们先集中考虑当前这个简单的方式。 这里我们使用关键字 function 、一个函数名、一对小括号定义了一个函数。 随后是一对花括号({})。花括号内部是调用函数时要运行的所有代码。
+
+ +
+
+
+
+
+

+要运行一个函数代码时,可以输入函数名加一对小括号。
+ +
+ +
让我们尝试一下。保存你的代码并刷新浏览器页面 。然后进入
+开发者工具 JavaScript 控制台,并输入以下代码:
+ +
+
+
+
+
+
+ +
checkGuess();
+ +

在按下 Return/Enter 之后,你应该会看到一个告警窗口,显示 "我是一个占位符";我们在代码中定义了一个函数,当我们调用它时,函数创建了一个告警窗口

+ +
+

: 后续课程 将讲解更多有关函数的知识。

+
+ +

运算符(Operator)

+ +

JavaScript 运算符允许我们执行比较,做数学运算,连接字符串,以及其他类似的事情。

+ +

请保存代码以免丢失,然后刷新浏览器页面,打开 开发者工具 JavaScript 控制台。然后我们就可以尝试下文中的示例了:把下表中“示例”一列中的每一项都原封不动输入进来,每次输入完毕后都按下  Return/Enter ,可以看到返回的结果。如果你无法访问浏览器开发者工具,你随时都可以使用下面的简易版内置控制台。

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300, "", "", "hide-codepen-jsfiddle") }}

+ +

首先让我们来看看算术运算符,例如:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符名称示例
+6 + 9
-20 - 15
*3 * 7
/10 / 5
+ +

您也可以使用 + 运算符将文本字符串连接在一起(术语“串联”(concatenation))。 尝试依次输入以下行:

+ +
let name = 'Bingo';
+name;
+let hello = ' says hello!';
+hello;
+let greeting = name + hello;
+greeting;
+ +

还有一些快捷操作符可用,称为 复合赋值操作符。 例如,如果你只希望在现有字符串末尾添加一个新串,可以这样做:

+ +
name += ' says hello!';
+ +

这等价于:

+ +
name = name + ' says hello!';
+ +

在执行真/假比较时(例如在条件语句中,见 {{anch("Conditionals", "下表")}}),我们使用 比较运算符,例如:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符名称示例
===严格等于(它们是否完全一样?)5 === 2 + 4
!==不等于(它们究竟哪里不一样?)'Chris' !== 'Ch' + 'ris'
<小于10 < 6
>大于10 > 20
+ +

条件语句(Conditional)

+ +

回到我们的 checkGuess() 函数,我们希望它不仅能够给出一个占位符消息,同时还能检查玩家是否猜对,并做出适当的反应。我想这并不难吧。

+ +

现在,将当前的 checkGuess() 函数替换为此版本:

+ +
function checkGuess() {
+  let userGuess = Number(guessField.value);
+  if (guessCount === 1) {
+    guesses.textContent = '上次猜的数:';
+  }
+  guesses.textContent += userGuess + ' ';
+
+  if (userGuess === randomNumber) {
+    lastResult.textContent = '恭喜你!猜对了';
+    lastResult.style.backgroundColor = 'green';
+    lowOrHi.textContent = '';
+    setGameOver();
+  } else if (guessCount === 10) {
+    lastResult.textContent = '!!!GAME OVER!!!';
+    setGameOver();
+  } else {
+    lastResult.textContent = '你猜错了!';
+    lastResult.style.backgroundColor = 'red';
+    if(userGuess < randomNumber) {
+      lowOrHi.textContent = '你猜低了!';
+    } else if(userGuess > randomNumber) {
+      lowOrHi.textContent = '你猜高了';
+    }
+  }
+
+  guessCount++;
+  guessField.value = '';
+  guessField.focus();
+}
+ +

唷——好多的代码!让我们来逐段探究。

+ + + +

如果是, 我们让 guesses 段落的文本内容等于“上次猜的数:”。如果不是就不用了。

+ + + +

事件(Event)

+ +

现在,我们有一个实现比较不错的 checkGuess() 函数了,但它现在什么事情也做不了,因为我们还没有调用它。 理想中,我们希望在点击“确定”按钮时调用它,为此,我们需要使用事件。 事件就是浏览器中发生的事儿,比如点击按钮、加载页面、播放视频,等等,我们可以通过调用代码来响应事件。 侦听事件发生的结构称为事件监听器(Event Listener),响应事件触发而运行的代码块被称为事件处理器(Event Handler)

+ +

checkGuess() 函数后添加以下代码:

+ +
guessSubmit.addEventListener('click', checkGuess);
+ +

这里为 guessSubmit 按钮添加了一个事件监听器。addEventListener() 方法包含两个可输入值(称为“参数”(argument)),监听事件的类型(本例中为“click”),和当事件发生时我们想要执行的代码(本例中为 checkGuess() 函数)。注意,addEventListener() 中作为参数的函数名不加括号。

+ +

现在,保存代码并刷新页面,示例应该能够工作了,但还不够完善。 现在唯一的问题是,如果玩家猜对或游戏次数用完,游戏将出错,因为我们尚未定义游戏结束时应运行的setGameOver() 函数。 现在,让我们补全所缺代码,并完善示例功能。

+ +

补全游戏功能

+ +

在代码最后添加一个 setGameOver() 函数,然后我们一起来看看它:

+ +
function setGameOver() {
+  guessField.disabled = true;
+  guessSubmit.disabled = true;
+  resetButton = document.createElement('button');
+  resetButton.textContent = '开始新游戏';
+  document.body.appendChild(resetButton);
+  resetButton.addEventListener('click', resetGame);
+}
+ + + +

现在我们需要定义 resetGame() 这个函数,依然放到代码底部:

+ +
function resetGame() {
+  guessCount = 1;
+
+  const resetParas = document.querySelectorAll('.resultParas p');
+  for (let i = 0 ; i < resetParas.length; i++) {
+    resetParas[i].textContent = '';
+  }
+
+  resetButton.parentNode.removeChild(resetButton);
+
+  guessField.disabled = false;
+  guessSubmit.disabled = false;
+  guessField.value = '';
+  guessField.focus();
+
+  lastResult.style.backgroundColor = 'white';
+
+  randomNumber = Math.floor(Math.random() * 100) + 1;
+}
+ +

这段较长的代码将游戏中的一切重置为初始状态,然后玩家就可以开始新一轮的游戏了。此段代码:

+ + + +

此刻一个能功能完善的(简易版)游戏就完成了。恭喜!

+ +

我们现在来讨论下其他很重要的代码功能,你可能已经看到过,但是你可能没有意识到这一点。

+ +

循环(Loop)

+ +

上面代码中有一部分需要我们仔细研读,那就是 for 循环。 循环是一个非常重要的编程概念,它让你能够重复运行一段代码,直到满足某个条件为止。

+ +

首先,请再次转到 浏览器开发工具 JavaScript 控制台 然后输入以下内容:

+ +
for (let i = 1; i < 21; i++) { console.log(i); }
+ +

发生了什么? 控制台中打印出了数字 1 到 20。 这正是循环所为。一个 for 循环需要三个输入值(参数):

+ +
    +
  1. 起始值:本例中我们从 1 开始计数,但其他任意数字也可以。 i也可以用任何你喜欢的名字替换,但一般约定用 i,因为它很短,且易于记忆。
  2. +
  3. 退出条件:这里我们指定 i < 21,直到i不再小于 21 前循环将继续。当 i 达到 21 时,循环将退出
  4. +
  5. 增加器:我们指定 i++,意思是向 i 加 1。i 值的每次变动都会引发循环的执行,直到 i 值等于 21(如前文所讲)。为简化问题,在本例中,我们使用console.log()在控制台打印出每次迭代时变量 i 的值。
  6. +
+ +

现在让我们来观察猜数字游戏中的循环 —— resetGame() 函数中可以找到以下内容:

+ +
let resetParas = document.querySelectorAll('.resultParas p');
+for (let i = 0 ; i < resetParas.length ; i++) {
+  resetParas[i].textContent = '';
+}
+ +

这段代码通过 {{domxref("Document.querySelectorAll", "querySelectorAll()")}} 方法创建了一个包含 <div class="resultParas"> 内所有段落的变量,然后通过循环迭代,删除每个段落的文本内容。

+ +

浅谈对象(Object)

+ +

在讨论前最后再改进一波。 在 let resetButton(脚本顶端部分)下方添加下面一行内容,然后保存文件:

+ +
guessField.focus();
+ +

这一行通过 {{domxref("HTMLElement.focus", "focus()")}} 方法让光标在页面加载完毕时自动放置于 {{htmlelement("input")}}  输入框内,这意味着玩家可以马上开始第一次猜测,而无需点击输入框。 这只是一个小的改进,却提高了可用性——为使用户能投入游戏提供一个良好的视觉线索。

+ +

深入分析一下。JavaScript 中一切都是对象。对象是存储在单个分组中的相关功能的集合。可以创建自己的对象,但这是较高阶的知识,我们今后才会谈及。现在,仅需简要讨论浏览器内置的对象,它们已经能够做许多有用的事情。

+ +

在本示例的特定情况下,我们首先创建一个 guessField 常量来存储对 HTML 中的文本输入表单域的引用,在文档顶部的声明区域中可以找到以下行:

+ +
const guessField = document.querySelector('.guessField');
+ +

使用 {{domxref("document")}} 对象的 {{domxref("document.querySelector", "querySelector()")}} 方法可以获得这个引用。querySelector() 需要一个信息——用一个 CSS选择器 可以选中需要引用的元素。

+ +

因为 guessField 现在包含一个指向 {{htmlelement("input")}} 元素的引用,它现在就能够访问一系列的属性(存储于对象内部的基础变量,其中一些的值无法改变)和方法(存储在对象内部的基础函数)。focus() 是 {{htmlelement("input")}} 元素可用方法之一,因此我们可以使用这行代码将光标聚焦于此文本框上︰

+ +
guessField.focus();
+ +

不包含对表单元素引用的变量不提供 focus()方法。例如,引用 {{htmlelement("p")}} 元素的guesses 常量,包含一个数字的 guessCount 变量。

+ +

操作浏览器对象

+ +

浏览器对象如何使用呢,下面我们来小试牛刀。

+ +
    +
  1. 首先在浏览器中打开你的程序。
  2. +
  3. 接下来打开 浏览器开发者工具, 并且切换到 JavaScript 控制台的标签页。
  4. +
  5. 输入 guessField ,控制台将会显示此变量包含一个 {{htmlelement("input")}} 元素。同时控制台还能自动补全运行环境中对象的名字,包括你的变量!
  6. +
  7. 现在输入下面的代码: +
    guessField.value = 'Hello';
    + value 属性表示当前文本区域中输入的值。 在输入这条指令后,你将看到文本域区中的文本被我们修改了!
  8. +
  9. 现在试试输入 guesses 然后回车。控制台会显示一个包含 {{htmlelement("p")}} 元素的变量。
  10. +
  11. 现在试试输入下面这一行: +
    guesses.value
    + 浏览器会返回 undefined,因为段落中并不存在 value
  12. +
  13. 为了改变段落中的文本内容, 你需要用 {{domxref("Node.textContent", "textContent")}} 属性来代替 value。试试这个: +
    guesses.textContent = '我的段落在哪里?';
    +
  14. +
  15. 下面是一些有趣的东西。 尝试依次输入下面几行: +
    guesses.style.backgroundColor = 'yellow';
    +guesses.style.fontSize = '200%';
    +guesses.style.padding = '10px';
    +guesses.style.boxShadow = '3px 3px 6px black';
    +
  16. +
  17. 页面上的每个元素都有一个 style 属性,它本身包含一个对象,其属性包含应用于该元素的所有内联 CSS 样式。 让我们可以使用 JavaScript 在元素上动态设置新的 CSS 样式。
  18. +
+ +

大功告成...

+ +

这个示例已经构建完毕,做得好!来尝试运行一下最终的代码,或者 看看我们的最终版本如果你的版本无法正常工作,请对照 源代码 进行检查。

+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/What_is_JavaScript", "Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps")}}

+ +

本章目录

+ + diff --git a/files/zh-cn/learn/javascript/first_steps/arrays/index.html b/files/zh-cn/learn/javascript/first_steps/arrays/index.html new file mode 100644 index 0000000000..e3cc48d6d5 --- /dev/null +++ b/files/zh-cn/learn/javascript/first_steps/arrays/index.html @@ -0,0 +1,522 @@ +--- +title: 数组 +slug: Learn/JavaScript/First_steps/Arrays +tags: + - JavaScript + - Join + - Pop + - Push + - shift + - split + - unshift + - 初学者 + - 数组 +translation_of: Learn/JavaScript/First_steps/Arrays +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps/Silly_story_generator", "Learn/JavaScript/First_steps")}}
+ +

在本模块的最后一篇文章中, 我们将看看数组 —— 一种将一组数据存储在单个变量名下的优雅方式。 现在我们看看它有什么用,然后探索如何来创建一个数组,检索、添加和删除存储在数组中的元素,以及其他更多的功能。

+ + + + + + + + + + + + +
前提:基本的电脑知识,对 HTML、CSS 语法有基础的理解,能理解什么是 JavaScript。
目的:理解什么是数组,和如何在 JavaScript 中操作数组。
+ +

数组是什么?

+ +

数组通常被描述为“像列表一样的对象”; 简单来说,数组是一个包含了多个值的对象。数组对象可以存储在变量中,并且能用和其他任何类型的值完全相同的方式处理,区别在于我们可以单独访问列表中的每个值,并使用列表执行一些有用和高效的操作,如循环 - 它对数组中的每个元素都执行相同的操作。 也许我们有一系列产品和价格存储在一个数组中,我们想循环遍历所有这些产品,并将它们打印在发票上,同时将所有产品的价格统计在一起,然后将总价格打印在底部。
+  

+ +

如果我们没有数组,我们必须将每个产品存储在一个单独的变量中,然后调用打印的代码,并为每个产品单独添加。 花费的时间要长得多,效率很低,而且也容易出错。 如果我们有 10 个产品需要添加发票,那就只是有点麻烦而已,但是 100 个,或者 1000 个呢? 我们稍后将在文章中使用这个例子。

+ +

像以前的文章一样,我们通过在 JavaScript 控制台中输入一些示例来了解数组的基础知识。 我们在下面提供了一个(您也可以在单独的选项卡或窗口中打开此控制台,或者如果您愿意,请使用浏览器的开发者工具控制台)。

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300) }}

+ +

创建数组

+ +

数组由方括号构成,其中包含用逗号分隔的元素列表。

+ +
    +
  1. 假设我们想在一个数组中存储一个购物清单 - 我们会做一些像下面这样的事情。 在您的控制台中输入以下行: +
    let shopping = ['bread', 'milk', 'cheese', 'hummus', 'noodles'];
    +shopping;
    +
  2. +
  3. 在这种情况下,数组中的每个项目都是一个字符串,但请记住,您可以将任何类型的元素存储在数组中 - 字符串,数字,对象,另一个变量,甚至另一个数组。 您也可以混合和匹配项目类型 - 它们并不都是数字,字符串等。尝试下面这些: +
    let sequence = [1, 1, 2, 3, 5, 8, 13];
    +let random = ['tree', 795, [0, 1, 2]];
    +
  4. +
  5. 尝试创建您自己的几个数组,然后再继续往下看。
  6. +
+ +

访问和修改数组元素

+ +

然后,您可以使用括号表示法访问数组中的元素,与 检索特定字符串字符 的方法相同。

+ +
    +
  1. 在您的控制台中输入以下内容: +
    shopping[0];
    +// returns "bread"
    +
  2. +
  3. 您还可以简单地为单个数组元素提供新值来修改数组中的元素。 例如: +
    shopping[0] = 'tahini';
    +shopping;
    +// shopping will now return [ "tahini", "milk", "cheese", "hummus", "noodles" ]
    + +
    Note: 我们以前说过,但还是提醒一下 —— 电脑从 0 开始计数!
    +
  4. +
  5. +

    请注意,数组中包含数组的话称之为多维数组。 您可以通过将两组方括号链接在一起来访问数组内的另一个数组。 例如,要访问数组内部的一个项目,即 random 数组中的第三个项目(参见上一节),我们可以这样做:

    + +
    random[2][2];
    +
  6. +
  7. 在继续之前,尝试对您的数组示例进行一些修改。 玩一玩,看看哪些有效,哪些无效。
  8. +
+ +

获取数组长度

+ +

你可以通过使用 {{jsxref("Array.prototype.length","length")}} 属性获取数组的长度(数组中有多少项元素),这与查找字符串的长度(以字符为单位)完全相同 。 尝试以下代码:

+ +
sequence.length;
+// should return 7
+ +

虽然 length 属性也有其他用途,但最常用于循环(循环遍历数组中的所有项)。 例如:

+ +
let sequence = [1, 1, 2, 3, 5, 8, 13];
+for (let i = 0; i < sequence.length; i++) {
+  console.log(sequence[i]);
+}
+ +

您将在以后的文章中正确地了解循环,但简而言之,这段代码的意思是:

+ +
    +
  1. 在数组中的元素编号 0 开始循环。
  2. +
  3. 在元素编号等于数组长度的时候停止循环。 这适用于任何长度的数组,但在这种情况下,它将在编号 7 的时候终止循环(这很好,因为我们希望最后一位元素的编号是 6)。
  4. +
  5. 对于每个元素,使用 console.log() 将其打印到浏览器控制台。
  6. +
+ +

一些有用的数组方法

+ +

在本节中,我们将介绍一些相当有用的数组方法,这些方法允许我们将字符串拆分为字符串数组,反之亦然,以及添加或删除元素。

+ +

字符串和数组之间的转换

+ +

通常,您会看到一个包含在一个长长的字符串中的原始数据,您可能希望将有用的项目分成更有用的表单,然后对它们进行处理,例如将它们显示在数据表中。 为此,我们可以使用 {{jsxref("String.prototype.split()","split()")}} 方法。 在其最简单的形式中,这需要一个参数,您要将字符串分隔的字符,并返回分隔符之间的子串,作为数组中的项。

+ +
+

Note:  好吧,从技术上讲,这是一个字符串方法,而不是一个数组方法,但是我们把它放在数组中,因为它在这里很合适。

+
+ +
    +
  1. 我们来玩一下这个方法,看看它是如何工作的。 首先,在控制台中创建一个字符串: +
    let myData = 'Manchester,London,Liverpool,Birmingham,Leeds,Carlisle';
    +
  2. +
  3. 现在我们用每个逗号分隔它: +
    let myArray = myData.split(',');
    +myArray;
    +
  4. +
  5. 最后,尝试找到新数组的长度,并从中检索一些项目: +
    myArray.length;
    +myArray[0]; // the first item in the array
    +myArray[1]; // the second item in the array
    +myArray[myArray.length-1]; // the last item in the array
    +
  6. +
  7. 您也可以使用 {{jsxref("Array.prototype.join()","join()")}} 方法进行相反的操作。 尝试以下: +
    let myNewString = myArray.join(',');
    +myNewString;
    +
  8. +
  9. 将数组转换为字符串的另一种方法是使用 {{jsxref("Array.prototype.toString()","toString()")}} 方法。 toString() 可以比 join() 更简单,因为它不需要一个参数,但更有限制。 使用 join() 可以指定不同的分隔符(尝试使用与逗号不同的字符运行步骤4)。 +
    let dogNames = ["Rocket","Flash","Bella","Slugger"];
    +dogNames.toString(); //Rocket,Flash,Bella,Slugger
    +
  10. +
+ +

添加和删除数组项

+ +

我们还没有涵盖添加和删除数组元素,现在让我们来看看。 我们将使用在上一节中最后提到的  myArray 数组。 如果您尚未遵循该部分,请先在控制台中创建数组:

+ +
let myArray = ['Manchester', 'London', 'Liverpool', 'Birmingham', 'Leeds', 'Carlisle'];
+ +

首先,要在数组末尾添加或删除一个项目,我们可以使用  {{jsxref("Array.prototype.push()","push()")}} 和 {{jsxref("Array.prototype.pop()","pop()")}}。

+ +
    +
  1. 让我们先使用 push() —— 注意,你需要添加一个或多个要添加到数组末尾的元素。 尝试下面的代码: + +
    myArray.push('Cardiff');
    +myArray;
    +myArray.push('Bradford', 'Brighton');
    +myArray;
    +
    +
  2. +
  3. 当方法调用完成时,将返回数组的新长度。 如果要将新数组长度存储在变量中。例如: +
    var newLength = myArray.push('Bristol');
    +myArray;
    +newLength;
    +
  4. +
  5. 从数组中删除最后一个元素的话直接使用 pop() 就可以。 例如: +
    myArray.pop();
    +
  6. +
  7. 当方法调用完成时,将返回已删除的项目。 你也可以这样做: +
    let removedItem = myArray.pop();
    +myArray;
    +removedItem;
    +
  8. +
+ +

{{jsxref("Array.prototype.unshift()","unshift()")}} 和 {{jsxref("Array.prototype.shift()","shift()")}} 从功能上与 {{jsxref("Array.prototype.push()","push()")}} 和 {{jsxref("Array.prototype.pop()","pop()")}} 完全相同,只是它们分别作用于数组的开始,而不是结尾。

+ +
    +
  1. 首先 unshift() ——尝试一下这个命令: + +
    myArray.unshift('Edinburgh');
    +myArray;
    +
  2. +
  3. 现在 shift() —— 尝试一下! +
    let removedItem = myArray.shift();
    +myArray;
    +removedItem;
    +
  4. +
+ +

积极学习:打印这些产品

+ +

我们回到前面描述的例子 —— 打印出发票上的产品名称和价格,然后计算总价格并将其印在底部。 在下面的可编辑示例中,包含数字的注释 —— 每个注释标记都是您必须向代码添加内容的地方。 它们如下:

+ +
    +
  1. 在 // number 1 注释下面是一些字符串,每个字符串包含一个产品名称和一个冒号分隔的价格。 我们希望您将其转换为一个数组,并将其存储在名为 products 的数组中。
  2. +
  3. // number 2 注释同一行的是 for 循环的开头。 在这行中,我们目前有 i <= 0,这是一个条件测试,导致 for循环 立即停止,因为它说“当 i 不再小于或等于0”时停止,而 i 从0开始。 我们希望您使用条件测试来替换它,当 i 不再小于 products 数组的长度时,该条件测试会停止循环。
  4. +
  5. 就在 // number 3 注释的下方,我们希望您编写一行代码,将当前数组项目(名称:价格)分成两个独立的项目,一个只包含该名称,一个只包含该价格。 如果您不确定如何执行此操作,请参阅有用的字符串方法文章以获得一些帮助,甚至更好的看看本文中的{{anch("转换字符串和数组")}}部分。
  6. +
  7. 作为上述代码行的一部分,您还需要将价格从字符串转换为数字。 如果你不记得如何做,请查看第一个字符串文章。
  8. +
  9. 有一个名为 total 的变量被创建,并在代码的顶部赋值为 0。 在循环内(在 // number 4 注释下面),我们希望您添加一行,将当前项目价格添加到循环中的迭代变量,以便在代码结尾处将正确的总数打印到发票上。 您可能需要一个赋值运算符来执行此操作。
  10. +
  11. 我们希望您改变 // number 5 注释的行,以便使  itemText 变量等于“当前项目名称 - $ 当前项目价格”,例如“Shoes - $ 23.99”,以此将每个项目的正确信息都印在发票上。 这只是简单的字符串连接,您应该对此很熟悉。
  12. +
+ + + +

{{ EmbedLiveSample('Playable_code', '100%', 600) }}

+ +

积极学习:前5个搜索

+ +

当您在 Web 程序中维护当前活动元素的记录时,{{jsxref("Array.prototype.push()","push()")}} 和 {{jsxref("Array.prototype.pop()","pop()")}} 是不错的方法。 例如,在动画场景中,您可能会有一系列表示当前显示的背景图像的对象,并且由于性能或混乱原因,您可能只需要一次显示 50 个。 当创建新对象并将其添加到数组中时,可以从数组中删除较旧的对象以保持所需的数量。

+ +

在这个例子中,我们将展示一种更简单的使用方法 - 在这里我们给你一个假的搜索网站,一个搜索框。 这个想法是,当在搜索框中输入时,列表中会显示5个先前的搜索字词。 当列表项目数量超过 5 时,每当新项目被添加到顶部时,最后一个项目开始被删除,因此总是显示5个以前的搜索字词。

+ +
+

Note: 在真正的搜索应用中,您可能可以点击先前的搜索字词返回上一次搜索,并显示实际的搜索结果! 我们现在只是保持简单的逻辑。

+
+ +

要完成该应用程序,我们需要您:

+ +
    +
  1. //number 1 注释下面添加一行,将输入到搜索框中的当前值添加到数组的开头。 这可以使用 searchInput.value 检索。
  2. +
  3. // number 2 注释下方添加一行,该行删除数组末尾的当前值。
  4. +
+ + + +

{{ EmbedLiveSample('Playable_code_2', '100%', 600) }}

+ +

总结

+ +

阅读本文后,我们相信您会明白数组是很有用的; 你会看到它们在 JavaScript 中随处可见,通常与循环相关,以便对数组中的每个元素做同样的事情。 我们将教你所有有用的基础知识,了解下一个模块中的循环,但现在你应该给自己鼓掌,并稍加休息; 您已经完成了本单元中的所有文章!

+ +

唯一需要做的就是通过这个模块的评估,这将测试你对之前的文章的理解。

+ +

相关链接

+ + + +

{{PreviousMenuNext("Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps/Silly_story_generator", "Learn/JavaScript/First_steps")}}

+ + + +

在本单元中

+ + diff --git a/files/zh-cn/learn/javascript/first_steps/index.html b/files/zh-cn/learn/javascript/first_steps/index.html new file mode 100644 index 0000000000..e53fc2761f --- /dev/null +++ b/files/zh-cn/learn/javascript/first_steps/index.html @@ -0,0 +1,57 @@ +--- +title: JavaScript 第一步 +slug: Learn/JavaScript/First_steps +tags: + - JavaScript + - 入门 + - 指南 + - 新手 +translation_of: Learn/JavaScript/First_steps +--- +
{{LearnSidebar}}
+ +

在第一个 JavaScript 板块,带领各位体验编写 JavaScript 程序前,首先回答一些基本问题:「什么是 JavaScript?」,「它看上去是什么样的?」,「它能做什么?」。此后,我们将详细讨论一些关键构件,例如变量、字符串、数值和数组。

+ +

事前准备

+ +

学习这个板块前,你不需要预先了解任何 JavaScript 知识,但你应当对 HTML 和 CSS 有所熟悉。我们建议学习 JavaScript 前,先完成以下板块阅读:

+ + + +
+

注意:如果你无法在你使用的电脑/平板/其他设备上创建自己的文件,尝试使用在线编程应用来运行(大部分)代码示例,例如 JSBinThimble

+
+ +

学习指南

+ +
+
什么是 JavaScript?
+
欢迎来到 MDN JavaScript 新手课程!第一篇文章,我们将从较高层次审视 JavaScript,解答诸如「它是什么?」、「它在做些什么?」的问题,确保你理解 JavaScript 的用途。
+
JavaScript 初体验
+
你已经学习了一些 JavaScript 理论,了解了可以用它做什么,接下来我们将通过一个非常实用的教程,带给你一节 JavaScript 基本特性速成课。在这里你将一步一步构建出一个「猜数字」游戏。
+
哪里出错了?JavaScript 疑难解答
+
构建上篇文章中的「猜数字」游戏时,你可能发现它没法运行。不要害怕——这篇文章来解救正为问题挠头的你,它为你提供一些从 JavaScript 程序中发现并解决问题的思路。
+
存储你需要的信息——变量
+
读过最近几篇文章,你应当了解 JavaScript 是什么,它能为你做什么,如何搭配其他 web 技术使用,以及从较高层次来看,它的主要特性是什么样的。这篇文章,我们将深入真正的基础,看看如何使用 JavaScript 的基本构件——变量。
+
JavaScript 中的基本运算——数值和运算符
+
这一课我们讨论 JavaScript 的运算——如何将运算符与其他特性结合使用,完美操作数值来实现需求。
+
文字处理——JavaScript 字符串
+
接下来将目光转向字符串——编程世界中文字片段被称为字符串。本文涉及你在学习 JavaScript 时应当了解的有关字符串的所有常见情形,例如生成字符串、字符串中的引用以及合并字符串。
+
实用字符串方法
+
我们已经了解字符串的基本内容,接下来再上一个台阶,思考利用字符串内建方法实现的实用操作,例如获取字符串长度、字符串合并与分割、替换字符串中特定字符,等等。
+
数组
+
这个版块最后一篇文章,我们来看数组——干净整洁地把一连串数据项存储在同一个变量名下。这里我们要理解为什么说它实用,探索如何创建数组,如何获取、添加、删除数组中的项目等等内容。
+
+ +

自我评估

+ +

下面的评估会检验你对上述学习指南中 JavaScript 基础的理解。

+ +
+
笑话生成器
+
这项评估中,你将运用你在这个版块的文章中学到的知识,构建一个生成随机笑话的好玩 app。玩得开心!
+
diff --git a/files/zh-cn/learn/javascript/first_steps/math/index.html b/files/zh-cn/learn/javascript/first_steps/math/index.html new file mode 100644 index 0000000000..b9bb3e012f --- /dev/null +++ b/files/zh-cn/learn/javascript/first_steps/math/index.html @@ -0,0 +1,429 @@ +--- +title: JavaScript中的基础数学 — 数字和操作符 +slug: Learn/JavaScript/First_steps/Math +translation_of: Learn/JavaScript/First_steps/Math +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps")}}
+ +

在本次课程中,我们讨论 JavaScript 中的数学 — 我们如何使用 {{Glossary("Operator","运算符")}} 和其他功能来成功地操作数字以完成我们的请求。

+ + + + + + + + + + + + +
前提:基本的计算机知识,对HTML和CSS初步了解,知道JavaScript是什么。
目标:熟悉 JavaScript 中 Math 的基础知识。
+ +

人人都爱数学

+ +

好吧,可能不是。有些人喜欢数学,有些人可能从在学校必须学习乘法表和长除法时就讨厌数学,还有人介于两者之间。但我们都不能否认,数学是生活的基本组成部分,我们离不了它。尤其如此,当我们学习编写 JavaScript 程序(或任何其他语言),我们所做的很多事情都依赖于处理数值数据,计算新值等。你将不会惊讶地认识到 JavaScript 有一套可用的全功能的数学功能。

+ +

本文仅讨论您现在需要了解的基本部分。

+ +

数字类型

+ +

在编程中,即使是人人熟知的最普遍的十进制数,也比你想象的要复杂的多。我们使用不同的术语来描述不同类型的十进制数,例如:

+ + + +

我们甚至有不同类型的数字系统! 十进制是基数10(意味着它在每列使用0-9),但是我们也有这样的东西:

+ + + +

在你开始担心你的大脑混乱之前,先停下来吧! 一开始,我们将在本课程中坚持使用十进制数; 你很少会遇到需要开始考虑其他类型的情况,如果有的话。

+ +

第二个好消息是,与其他一些编程语言不同,JavaScript只有一个数据类型用来表示数字(包括 integers 和 decimals ),您猜对了,{{jsxref("Number")}}。 这意味着,你在JavaScript中处理的任何类型的数字,都以完全相同的方式处理它们。

+ +

这是我们的全部数字

+ +

让我们快点玩一些数字,以重新定义我们所需要的基本语法。 在您的开发工具JavaScript控制台中输入下面列出的命令。

+ +

在新窗口中打开

+ +
    +
  1. 首先,我们先声明一对变量,并分别用一个整数和一个浮点数来初始化它们,然后再输入变量名来检查是否正确: +
    let myInt = 5;
    +let myFloat = 6.667;
    +myInt;
    +myFloat;
    +
  2. +
  3. 数值键入不带引号 —— 在继续之前尝试声明和初始化更多包含数字的变量。
  4. +
  5. 现在我们来看看我们的原始变量是否是相同的数据类型。 在JavaScript中有一个称为{{jsxref("Operators / typeof", "typeof")}} 的运算符。 输入如下所示的两行: +
    typeof myInt;
    +typeof myFloat;
    + 在这两种情况下,都应该返回 "number" —— 这使得事情变得更简单,因为若是不同的数字具有不同的数据类型,那么我们还须以不同的方式处理它们。呦!
  6. +
+ +

算术运算符

+ +

算术运算符是我们用来做和的基本运算符:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符名称作用示例
+加法两个数相加。6 + 9
-减法从左边减去右边的数。20 - 15
*乘法两个数相乘。3 * 7
/除法用右边的数除左边的数10 / 5
%求余(有时候也叫取模) +

在你将左边的数分成同右边数字相同的若干整数部分后,返回剩下的余数

+
8 % 3 (返回 2,8除以3的倍数,余下2 。)
** +

取底数的指数次方,即指数所指定的底数相乘。它在EcmaScript 2016 中首次引入。

+
5 ** 5 (返回 3125,相当于 5 * 5 * 5 * 5 * 5 。)
+ +
+

Note: 你以后有时候会看到参与算术计算的数字被称为 操作数({{Glossary("Operand", "operands")}})。

+
+ +
+

Note: 有时你可能会看到使用较旧的 {{jsxref("Math.pow()")}} 方法表达的指数,该方法的工作方式非常相似。 例如,在 Math.pow(7, 3)  中,7 是基数,3 是指数,因此表达式的结果是 343Math.pow(7, 3) 相当于 7 ** 3

+
+ +

我们可能不需要教你如何做基础数学,但我们想测试你对所涉及的语法的理解。 尝试将下面的示例输入到开发者工具JavaScript控制台中。

+ +
    +
  1. 首先尝试输入一些简单的例子,例如 +
    10 + 7
    +9 * 8
    +60 % 3
    +
  2. +
  3. 您还可以尝试声明变量并用数字初始化变量,然后尝试使用这些变量来求和 - 求和中变量的行为与直接用其持有的数来求和完全一样。 例如: +
    let num1 = 10;
    +let num2 = 50;
    +9 * num1;
    +num1 ** 3;
    +num2 / num1;
    +
  4. +
  5. 最后在本节中,尝试输入一些更复杂的表达式,如: +
    5 + 10 * 3;
    +num2 % 9 * num1;
    +num2 + num1 / 8 + 2;
    +
  6. +
+ +

这最后的一组计算中可能没有给出你期望的结果; 下面的部分也许能告诉你为什么。

+ +

运算符优先级

+ +

我们来看看上面的最后一个例子,假设num2的值为50,num1的值为10(如上所述):

+ +
num2 + num1 / 8 + 2;
+ +

一般人,你会将它看作“50加10等于60”,然后“8加2等于10”,最后“60除以10等于6”。

+ +

但浏览器的“10除以8等于1.25”,那么“50加1.25加2等于53.25”。

+ +

这是因为运算符优先级 —— 一些运算符将在计算算式(在编程中称为表达式)的结果时先于其他运算符被执行。 JavaScript中的运算符优先级与学校的数学课程相同 - 乘法和除法总是先完成,然后是加法和减法(总是从左到右进行计算)。

+ +

如果想要改变计算优先级,可以把想要优先计算的部分用括号围住。 所以要得到结果为6,我们可以这样做:

+ +
(num2 + num1) / (8 + 2);
+ +

尝试看看。

+ +
+

Note: 注意:可以在表达式和运算符中找到所有JavaScript运算符的完整列表及其优先级。

+
+ +

自增和自减运算符

+ +

有时候,您需要反复把一个变量加1或减1。 这可以方便地使用增量(++)和递减( -- )运算符来完成。 我们在JavaScript 初体验文章的“猜数字”游戏中使用了++,当我们添加1到我们的guessCount变量来跟踪用户在每次转动之后剩下的猜测时。

+ +
guessCount++;
+ +
+

Note: 它们最常用于 循环 中,您将在以后的课程中了解。 例如,假设您想循环查看价格表,并为每个价格增加销售税。 您可以使用循环依次查看每个值,并在每种情况下进行必要的计算,以添加销售税。 当需要时,增量器用于移动到下一个值。 我们实际上提供了一个简单的例子,显示了如何完成 ——  在线查看效果,并 查看源代码,看看是否可以发现增量器! 我们稍后将会详细介绍循环。

+
+ +

我们来试试看你们的控制台。 首先,请注意,您不能将这些直接应用于一个数字,这可能看起来很奇怪,但是我们为变量赋值一个新的更新值,而不是对该值进行操作。 以下将返回错误:

+ +
3++;
+ +

所以,你只能增加一个现有的变量。 尝试这个:

+ +
let num1 = 4;
+num1++;
+ +

好的,第二个奇怪的东西! 执行此操作时,您会看到返回值为4,这是因为浏览器返回当前值,然后增加变量。 如果您再次返回变量值,则可以看到它已经递增:

+ +
num1;
+ +

递减 -- 同样如此,尝试以下操作:

+ +
let num2 = 6;
+num2--;
+num2;
+ +
+

Note: 您可以使浏览器以其他方式进行操作 - 递增/递减变量,然后返回值 - 将操作符放在变量的开头,而不是结束。 再次尝试上面的例子,但这次使用 ++num1--num2

+
+ +

赋值运算符

+ +

赋值运算符是向变量分配值的运算符。 我们已经使用了最基本的一个很多次了:=, 它只是将右边的值赋给左边的变量 ,即:

+ +
let x = 3; // x 的值是 3
+let y = 4; // y 的值是 4
+x = y; // x 和 y 有相同的值, 4
+ +

但是还有一些更复杂的类型,它们提供了有用的快捷方式,可以使您的代码更加清洁和高效。 最常见的如下:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符名称作用示例等价于
+=加法赋值右边的数值加上左边的变量,然后再返回新的变量。x = 3;
+ x += 4;
x = 3;
+ x = x + 4;
-=减法赋值左边的变量减去右边的数值,然后再返回新的变量。x = 6;
+ x -= 3;
x = 6;
+ x = x - 3;
*=乘法赋值左边的变量乘以右边的数值,然后再返回新的变量。x = 2;
+ x *= 3;
x = 2;
+ x = x * 3;
/=除法赋值左边的变量除以右边的数值,然后再返回新的变量。x = 10;
+ x /= 5;
x = 10;
+ x = x / 5;
+ +

尝试在你的控制台中输入上面的一些示例,以了解它们的工作原理。 在每种情况下,你是否可以猜出在输入第二行之前的值。

+ +

请注意,您可以愉快地使用每个表达式右侧的其他变量,例如:

+ +
let x = 3; // x 包含值 3
+let y = 4; // y 包含值 4
+x *= y; // x 现在包含值 12
+ +
+

Note: 虽然有很多可用的赋值运算符, 但是这些是你现在应该学习的基本的一类。

+
+ +

主动学习:调整画布框的大小

+ +

在这个练习中,我们将让你填写一些数字和操作符来操纵一个框的大小。 该框使用称为{{domxref("Canvas API", "", "", "true")}}的浏览器API绘制。 没有必要担心这是如何工作的 - 现在只关注数学。 盒子的宽度和高度(以像素为单位)由变量 xy 定义,变量 xy 最初都被赋值为50。

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/editable_canvas.html", '100%', 620)}}

+ +

新窗口打开

+ +

在上面的可编辑代码框中,有两行标有清晰的注释,我们希望你更新以使框增长/缩小到某些大小,在每种情况下使用某些操作符和/或值。 我们希望你回答以下问题:

+ + + +

如果你完全混淆了代码,别担心。 您可以随时按“重置”按钮,使事情恢复正常。 在您正确回答了上述所有问题后,可以自由地使用代码或创建自己的挑战。

+ +

比较运算符

+ +

有时,我们将要运行真/假测试,然后根据该测试的结果进行相应的操作 - 为此,我们使用比较运算符。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符名称作用示例
===严格等于测试左右值是否相同5 === 2 + 4
!==严格不等于测试左右值是否相同5 !== 2 + 3
<小于测试左值是否小于右值。10 < 6
>大于测试左值是否大于右值10 > 20
<=小于或等于测试左值是否小于或等于右值。3 <= 2
>=大于或等于测试左值是否大于或等于正确值。5 >= 4
+ +
+

Note: 您可能会看到有些人在他们的代码中使用==!=来判断相等和不相等,这些都是JavaScript中的有效运算符,但它们与===/!==不同,前者测试值是否相同, 但是数据类型可能不同,而后者的严格版本测试值和数据类型是否相同。 严格的版本往往导致更少的错误,所以我们建议您使用这些严格的版本。

+
+ +

如果您尝试在控制台中输入这些值,您将看到它们都返回 true/false 值 - 我们在上一篇文章中提到的那些布尔值。 这些是非常有用的,因为它们允许我们在我们的代码中做出决定 - 每次我们想要选择某种类型时,都会使用这些代码,例如:

+ + + +

当我们在以后的的文章中查看条件语句时,我们将介绍如何编写这样的逻辑。 现在,我们来看一个简单的例子:

+ +
<button>Start machine</button>
+<p>The machine is stopped.</p>
+
+ +
const btn = document.querySelector('button');
+const txt = document.querySelector('p');
+
+btn.addEventListener('click', updateBtn);
+
+function updateBtn() {
+  if (btn.textContent === 'Start machine') {
+    btn.textContent = 'Stop machine';
+    txt.textContent = 'The machine has started!';
+  } else {
+    btn.textContent = 'Start machine';
+    txt.textContent = 'The machine is stopped.';
+  }
+}
+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/conditional.html", '100%', 100)}}

+ +

新窗口打开

+ +

您可以在updateBtn()函数内看到正在使用的等号运算符。 在这种情况下,我们不会测试两个数学表达式是否具有相同的值 - 我们正在测试一个按钮的文本内容是否包含某个字符串 - 但它仍然是工作原理。 如果按钮当前按“启动机”,则将其标签更改为“停机”,并根据需要更新标签。 如果按下按钮当前正在说“停机”,我们再次将显示器交换回来。

+ +
+

Note: 这种在两个状态之间来回交换的行为通常被称为 切换 (toggle)。它在一个状态和另一个状态之间切换 - 点亮,熄灭等

+
+ +

总结

+ +

在本文中,我们已经介绍了现在需要了解JavaScript中数字的基本信息。 你会发现,在你学习JavaScript过程中,num类型的数据一直都在被使用,所以熟练的掌握它是一个不错的选择。 如果你是那些不喜欢数学的人之一,你应该庆幸这一章内容很简短。

+ +

在下一篇文章中,我们将探讨文本,以及JavaScript如何让我们操纵它。

+ +
+

Note:  如果您喜欢数学,并希望阅读更多关于它如何在JavaScript中实现的, 那么你可以在 MDN's main JavaScript 部分读到更多关于它的内容。对于学习数字与日期 和 表达式与运算符 来说,那是一个不错的地方。

+
+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps")}}

+ +

在这个模块

+ + diff --git a/files/zh-cn/learn/javascript/first_steps/silly_story_generator/index.html b/files/zh-cn/learn/javascript/first_steps/silly_story_generator/index.html new file mode 100644 index 0000000000..f99ff16949 --- /dev/null +++ b/files/zh-cn/learn/javascript/first_steps/silly_story_generator/index.html @@ -0,0 +1,239 @@ +--- +title: 笑话生成器 +slug: Learn/JavaScript/First_steps/Silly_story_generator +tags: + - JavaScript + - 初学者 + - 变量 + - 字符串 + - 学习 + - 操作符 + - 数字 + - 数组 + - 测试 + - 脚本代码 + - 课程设计 +translation_of: Learn/JavaScript/First_steps/Silly_story_generator +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}
+ +

本节是一个小测验,要求你运用所学知识制作一个笑话生成器。祝玩的愉快!

+ + + + + + + + + + + + +
预备知识:请读完本章所有小节的内容后再开始这个测验。
目标:测试你对变量、数字、操作符、字符串和数组等 Javascript 基本概念的理解程度。
+ +

起点

+ +

测验开始之前需要下载并保存 index.htmlstyle.cssraw-text.txt

+ +
+

注: 你还可以用类似 JSBin 或 Thimble 这些在线编辑器来完成测验。你可以把 HTML、CSS 及 JavaScript 代码复制过去。如果你选的工具没有独立的 JavaScript 版面,可以随时在 HTML 页面中添加 <script> 元素。

+
+ +

项目简介

+ +

我们提供了一些原始的 HTML / CSS,以及若干字符串和 JavaScript 函数,还需要你来编写一些 JavaScript 代码让项目运行起来:

+ + + +

可以尝试操作一下:(别偷看源代码哦!)

+ + + +

{{ EmbedLiveSample('Silly_story_generator', '100%', 350, "", "", "hide-codepen-jsfiddle") }}

+ +
+

译注: 点击在线试用 汉化版本。有兴趣还可以在本节结束后回来 看看代码。(没兴趣就跳过吧 :)

+
+ +

步骤

+ +

以下是你的工作。

+ +

初始化变量和函数:

+ +
    +
  1. 将刚下载的文本文件中的“1. 定义变量和函数”标题项下所有代码复制粘贴至 main.js 中。此时你就有了三个变量(customName 是对“输入自定义的名字”文本框的引用,randomize 是对“随机生成笑话”按钮的引用,story 是对 HTML 底部的、准备存放笑话的 {{htmlelement("p")}} 元素的引用)和一个函数(randomValueFromArray() 取一个数组作参数,随机返回数组中的一个元素)。
  2. +
  3. 然后是文本文件的第二节——“2. 纯文本字符串”。这里包含了一些字符串,这些字符串是项目的输入信息。你应该在 main.js 文件中用变量来保存它们。 +
      +
    1. storyText 变量保存第一个长字符串,“今天气温……”。
    2. +
    3. insertX 数组保存第一组三个字符串,“怪兽威利……”。
    4. +
    5. insertY 数组保存第二组三个字符串。“肯德基……”。
    6. +
    7. insertZ 数组保存第三组三个字符串。“自燃了……”。
    8. +
    +
  4. +
+ +

放置事件处理器并补全:

+ +
    +
  1. 返回刚才的文本文件。
  2. +
  3. 将“3. 事件监听器和未完成的函数定义”标题项下的代码复制粘贴至 main.js 文件。这将: +
      +
    • randomize 变量增加一个点击事件的监听器。于是当所引用的按钮被点击时,result() 函数就会运行。
    • +
    • 为代码添加一个未完成的 result() 函数定义。本测验剩下的工作就是完成这个函数,让程序正常运行起来。
    • +
    +
  4. +
+ +

补全 result() 函数:

+ +
    +
  1. newStory 的值设置为 storyText。声明新变量有必要的,只有这样才能在每次按下按钮后、在函数运行时生成一个新的随机笑话。如果直接操作 storyText 则只能生成一次新故事
  2. +
  3. xItemyItem 和 zItem 分别设置为 randomValueFromArray(insertX)randomValueFromArray(insertY)randomValueFromArray(insertZ)
  4. +
  5. 接下来将 newStory 中的占位符(:inserta::insertb::insertc: )替换为 xItemyItem 和 zItem。有专用的字符串方法可供使用,并用该方法的返回值为 newStory 赋值。每当按下按钮时,这些占位符都会替换为随机的笑话字符串。再给你一点提示,我们所说的这种方法每次只会将所找到的首个子字符串进行替换,因此该方法对某个占位符需要执行两次。
  6. +
  7. 在第一个 if 块中再次调用这个字符串替换方法,以使 newStory 字符串中的名字“李雷”替换为变量 name 的值 。这里我们说:“如果 customName 中有值,就把故事里的 “李雷”替换成它。” 如果是汉化版将newStory中的“李雷”替换成 name 的值;
  8. +
  9. 在第二个 if 块中检查 american 单选按钮是否被选中。如果选中,就要将故事中的重量和温度值从公斤和摄氏度转换为磅和华氏度,具体事项如下: +
      +
    1. 确定英美单位的转换公式。
    2. +
    3. 定义变量 weighttemperature 的行中,分别将美制单位按公式转化为英制,用 Math.round() 对计算结果取整。然后将英式单位连接到末尾。
    4. +
    5. 就在上述两个变量的定义下方增加两个字符串置换操作,将“35 摄氏度”替换为 temperature 的值,将“140 公斤”替换为 weight 的值。
    6. +
    +
  10. +
  11. 最后,在函数倒数第二行,将 story.textContent(程序中显示笑话结果的段落) 赋值为 newStory
  12. +
+ +

提示

+ + + +

测验

+ +

如果你是在课堂上进行这个测验,你可以把作品交给导师或教授去打分了。如果你是在自学,也可以在 本节测验的讨论页 或者 Mozilla 聊天室 #mdn 频道取得帮助。要自己先尝试,作弊是不会有收获的!

+ +

{{PreviousMenu("Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}

+ +

本章目录

+ + diff --git a/files/zh-cn/learn/javascript/first_steps/strings/index.html b/files/zh-cn/learn/javascript/first_steps/strings/index.html new file mode 100644 index 0000000000..36352b5f48 --- /dev/null +++ b/files/zh-cn/learn/javascript/first_steps/strings/index.html @@ -0,0 +1,288 @@ +--- +title: 文本处理 — JavaScript中的字符串 +slug: Learn/JavaScript/First_steps/Strings +tags: + - JavaScript + - Join + - 初学者 + - 字符串 + - 指南 + - 文章 + - 脚本编写 +translation_of: Learn/JavaScript/First_steps/Strings +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps")}}
+ +

接下来,我们将把注意力转向文本片段——也就是编程中所说的字符串。在本文中,我们将了解在学习JavaScript时,您应该了解的关于字符串的所有常见事项,例如创建字符串、在字符串中转义引号,和连接字符串。

+ + + + + + + + + + + + +
预备知识:基本的计算机读写能力,对HTML和CSS的基本理解,对JavaScript的理解。
目标:要熟悉JavaScript中字符串的基本知识。
+ +

语言的力量

+ +

语言对人类非常重要——它们是我们交流的重要组成部分。由于Web是一种主要基于文本的媒介,旨在让人们进行交流和分享信息,因此对我们来说,掌握它所出现的单词是很有用的。{{glossary("HTML")}}为我们的文本提供了结构和意义, {{glossary("CSS")}} 允许我们精确地设计它的样式,JavaScript包含许多操作字符串的特性,创建定制的欢迎消息,在需要时显示正确的文本标签,将术语排序到所需的顺序,等等。

+ +

到目前为止,我们在课程中展示的所有程序都涉及到一些字符串操作。

+ +

字符串 — 基本知识

+ +

字符串与数字的处理方式第一眼看上去十分相似,但是当您深入挖掘时,您将会看到一些显著的差异。让我们首先在一个控制台输入一些基本的行来熟悉一下。
+ 我们在下面提供了一个(您也可以在一个单独的选项卡或窗口中打开这个控制台,或者如果您愿意使用浏览器开发人员控制台)。

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300) }}

+ +

创建一个字符串

+ +
    +
  1. 首先, 输入下面的代码: +
    let string = 'The revolution will not be televised.';
    +string;
    + 就像我们处理数字一样,我们声明一个变量,用一个字符串值初始化它,然后返回值。这里惟一的区别是,在编写字符串时,我们需要在字符串上加上引号。
  2. +
  3. 如果你不这样做,或者在书写过程中,漏掉其中一个引号,你就会得到一个错误。
    + 试着输入以下几行: +
    let badString = This is a test;
    +let badString = 'This is a test;
    +let badString = This is a test';
    + 这些行不起作用,因为没有引号的任何文本字符串都被假定为变量名、属性名、保留字或类似。如果浏览器不能找到它,那么将会引发语法错误(例如:"missing ; before statement")。
    + 如果浏览器能够识别字符串从哪里开始,但是不能找到字符串的结尾符,如第二行所示,那么它则会提示这样的错误(“unterminated string literal”)。如果您写的程序目前也引发这样的错误,那么请你回过头来仔细检查你的代码,看是否漏写了引号。
  4. +
  5. 如果您之前定义了变量字符串,下面的操作将会起作用 — 现在来试一试: +
    let badString = string;
    +badString;
    + +

    现在将 string 的值赋值给 badString,赋值之后,两个字符串的值相等。

    +
  6. +
+ +

单引号和双引号

+ +
    +
  1. 在JavaScript中,您可以选择单引号或双引号来包裹字符串。
    + 下面两种方式都可以: +
    let sgl = 'Single quotes.';
    +let dbl = "Double quotes";
    +sgl;
    +dbl;
    +
  2. +
  3. 两者之间几乎没有什么区别,根据个人偏好来使用。但是,您应该选择一个并坚持使用它,不一致的引号混用代码可能会让人很迷惑,特别是如果您在同一个字符串中使用不同的引号!
    + 下面将返回一个错误: +
    let badQuotes = 'What on earth?";
    +
  4. +
  5. 浏览器会认为字符串没有被关闭,因为在字符串中您没有使用其他类型的引号。
    + 例如,这两种情况都是可以的: +
    let sglDbl = 'Would you eat a "fish supper"?';
    +let dblSgl = "I'm feeling blue.";
    +sglDbl;
    +dblSgl;
    +
  6. +
  7. 但是,您不能在字符串中包含相同的引号,因为它是用来包含它们的。下面将会出现错误,因为它会混淆浏览器和字符串的结束位置: +
    let bigmouth = 'I've got no right to take my place...';
    + 这个指引将会让我们很好地进入下一个主题。
  8. +
+ +

转义字符串中的字符

+ +

要修复我们之前的问题代码行,我们需要避免引号的问题。转义字符意味着我们对它们做一些事情,以确保它们被识别成文本,而不是代码的一部分。在JavaScript中,我们通过在字符之前放一个反斜杠来实现这一点。试试这个:

+ +
let bigmouth = 'I\'ve got no right to take my place...';
+bigmouth;
+ +

这回正常了。你可以用别的方式来达到一样的目的, 例如. \", 除此之外有一些特殊的代码 。更多细节请参见转义符号

+ +

连接字符串

+ +
    +
  1. 连接是一个很花哨的编程词,意思是“连接在一起”。在JavaScript中连接字符串使用加号(+)操作符,我们也用它来将数字加在一起,但是在这种情况下,它做了一些不同的事情。让我们在控制台中尝试一个例子。 +
    let one = 'Hello, ';
    +let two = 'how are you?';
    +let joined = one + two;
    +joined;
    + 变量 joined 的值的结果,它包含的值为 "Hello, how are you?"。
  2. +
  3. 最后一个例子中, 我们只是把两个字符串连接在一起,但是你可以喜欢连接多少就多少个, 只需要在它们之间加上 + 操作符。试试这个: +
    let multiple = one + one + one + one + two;
    +multiple;
    +
  4. +
  5. 你还能用真实的字符串和变量来混合。试试这个: +
    let response = one + 'I am fine — ' + two;
    +response;
    +
  6. +
+ +
+

注意: 当您在您的代码中输入一个实际的字符串时,用单引号或双引号括起来,它被称为字符串文字。

+
+ +

上下文中的串联

+ +

让我们看一下在操作中使用的连接——这是本课程早些时候的一个例子:

+ +
<button>Press me</button>
+ +
const button = document.querySelector('button');
+
+button.onclick = function() {
+  let name = prompt('What is your name?');
+  alert('Hello ' + name + ', nice to see you!');
+}
+ +

{{ EmbedLiveSample('上下文中的串联', '100%', 50, "", "", "hide-codepen-jsfiddle") }}

+ +

这里我们使用的是第4行中的 {{domxref("window.prompt()", "window.prompt()")}} 函数, 它要求用户通过一个弹出对话框回答一个问题然后将他们输入的文本存储在一个给定的变量中 — 在这个例子中是就是 name 变量。然后,我们在第5行中使用  {{domxref("window.alert()","window.alert()")}}  函数来显示另一个弹出窗口,其中包含一个字符串,我们用两个字符串常量和name变量通过连接进行组合。

+ +

数字与字符

+ +
    +
  1. 当我们尝试添加(或连接)一个字符串和一个数字时,会发生什么?
    + 让我们在我们的控制台中尝试一下: +
    'Front ' + 242;
    +
    + 您可能会认为这会抛出一个错误,但它运行得很好。
    + 试图将字符串表示为一个数字并不是很讲的通,但是用数字表示一个字符串则不然,因此浏览器很聪明地将数字转换为字符串,并将这两个字符串连接在一起。
  2. +
  3. 你甚至可以用两个数字来这么操作——你可以通过用引号将数字包装成一个字符串。尝试以下方法(我们使用typeof操作符来检查变量是一个数字还是一个字符串): +
    let myDate = '19' + '67';
    +typeof myDate;
    +
  4. +
  5. 如果您有一个数值变量,您想要将其转换为字符串,并且不改变其他地方,或者您想将一个字符串转换为一个数字而不改变其其他地方,那么您可以使用以下两个构造: +
      +
    • 如果可以的话, {{jsxref("Number")}} 对象将把传递给它的任何东西转换成一个数字。
      + 试一试: +
      let myString = '123';
      +let myNum = Number(myString);
      +typeof myNum;
      +
    • +
    • 另一方面,每个数字都有一个名为 toString() 的方法,它将把它转换成等价的字符串。
      + 试试这个: +
      let myNum = 123;
      +let myString = myNum.toString();
      +typeof myString;
      +
    • +
    + 这些结构在某些情况下是非常有用的,例如,如果一个用户将一个数字输入到一个表单文本字段中,这将是一个字符串,但是如果你想要将这个数字添加到某些东西中时,你需要它是一个数字,所以你可以通过 Number() 来处理这个问题。我们在数字猜谜游戏中第54行就是这么做的。
  6. +
+ +

结论

+ +

这就是JavaScript中所涉及的字符串的基本内容。在下一篇文章中,我们将在此基础上,研究JavaScript中字符串的一些内置方法,以及如何使用它们来操纵我们的字符串,使之成为我们想要的形式。

+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps")}}

+ +

+ +

diff --git a/files/zh-cn/learn/javascript/first_steps/test_your_skills_colon__variables/index.html b/files/zh-cn/learn/javascript/first_steps/test_your_skills_colon__variables/index.html new file mode 100644 index 0000000000..af9b56b9ae --- /dev/null +++ b/files/zh-cn/learn/javascript/first_steps/test_your_skills_colon__variables/index.html @@ -0,0 +1,78 @@ +--- +title: 'Test your skills: variables' +slug: 'Learn/JavaScript/First_steps/Test_your_skills:_variables' +translation_of: 'Learn/JavaScript/First_steps/Test_your_skills:_variables' +--- +
{{learnsidebar}}
+ +

这个能力测试用于评估你自己是否理解了 如何存储你需要的信息 — 变量 这篇文章.

+ +
+

Note: You can try out solutions in the interactive editors below, however it may be helpful to download the code and use an online tool such as CodePen, jsFiddle, or Glitch to work on the tasks.
+
+ 如果你遇到问题需要我们帮助 — 请前往在这一页的底部的 {{anch("Assessment or further help")}} 部分.

+
+ +
+

Note: In the examples below, if there is an error in your code it will be outputted into the results panel on the page, to help you try to figure out the answer (or into the browser's JavaScript console, in the case of the downloadable version).

+
+ +

Variables 1

+ +

In this task we want you to:

+ + + +

Try updating the live code below to recreate the finished example:

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/variables/variables1.html", '100%', 400)}}

+ +
+

Download the starting point for this task to work in your own editor or in an online editor.

+
+ +

Variables 2

+ +

In this task you need to add a new line to correct the value stored in the existing myName variable to your own name.

+ +

Try updating the live code below to recreate the finished example:

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/variables/variables2.html", '100%', 400)}}

+ +
+

Download the starting point for this task to work in your own editor or in an online editor.

+
+ +

Variables 3

+ +

The final task for now — in this case you are provided with some existing code, which has two errors present in it. The results panel should be outputting the name Chris, and a statement about how old Chris will be in 20 years' time. How can you fix the problem and correct the output?

+ +

Try updating the live code below to recreate the finished example:

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/variables/variables3.html", '100%', 400)}}

+ +
+

Download the starting point for this task to work in your own editor or in an online editor.

+
+ +

Assessment or further help

+ +

You can practice these examples in the Interactive Editors above.

+ +

If you would like your work assessed, or are stuck and want to ask for help:

+ +
    +
  1. Put your work into an online shareable editor such as CodePen, jsFiddle, or Glitch. You can write the code yourself, or use the starting point files linked to in the above sections.
  2. +
  3. Write a post asking for assessment and/or help at the MDN Discourse forum Learning category. Your post should include: +
      +
    • A descriptive title such as "Assessment wanted for Variables 1 skill test".
    • +
    • Details of what you have already tried, and what you would like us to do, e.g. if you are stuck and need help, or want an assessment.
    • +
    • A link to the example you want assessed or need help with, in an online shareable editor (as mentioned in step 1 above). This is a good practice to get into — it's very hard to help someone with a coding problem if you can't see their code.
    • +
    • A link to the actual task or assessment page, so we can find the question you want help with.
    • +
    +
  4. +
diff --git a/files/zh-cn/learn/javascript/first_steps/useful_string_methods/index.html b/files/zh-cn/learn/javascript/first_steps/useful_string_methods/index.html new file mode 100644 index 0000000000..0dda086985 --- /dev/null +++ b/files/zh-cn/learn/javascript/first_steps/useful_string_methods/index.html @@ -0,0 +1,474 @@ +--- +title: 有用的字符串方法 +slug: Learn/JavaScript/First_steps/Useful_string_methods +tags: + - JavaScript + - String + - 大写 + - 字符串 + - 小写 + - 替换 + - 格式 + - 长度 +translation_of: Learn/JavaScript/First_steps/Useful_string_methods +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}
+ +

现在我们学习基本的字符串语法, 让我们开始思考一下我们可以对内置方法的字符串做什么有用的操作,例如查找文本字符串的长度,加入和分割字符串, 将字符串中的一个字符替换为另一个字符。

+ + + + + + + + + + + + +
前提:基本的电脑知识, 对HTML和CSS有一定的了解,最好是懂一点javascript知识。
目的:明白字符串这个对象,学会使用字符串的基本方法去处理字符串
+ +

把字符串当作对象

+ +

我们曾经说过,现在我们重申一遍—在javascript中,一切东西都可以被当作对象。例如我们创建一个字符串。

+ +
let string = 'This is my string';
+ +

一旦你的变量成为字符串对象实例, 你就可以有大量的原型和方法编辑它. 如果你进入{{jsxref("String")}}对象页并观察页面旁边的列表你就会明白这一点。

+ +

可能现在你的大脑开始迷糊了,不要担心! 在你的学习进程中你真的不需要过早地理解大部分这方面知识,但是接下来我们这儿要看的是你要经常使用的一些知识。

+ +

现在我们在控制台中加些示例 ,我们已经提供了以下示例(你可在单独打开控制台标签或窗口,或者选择使用浏览器开发者控制台

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300) }}

+ +

获得字符串的长度

+ +

这很简单 — 你可以很轻松的使用 {{jsxref("String.prototype.length", "length")}} 属性. 尝试输入以下的两行代码:

+ +
let browserType = 'mozilla';
+browserType.length;
+ +

这个结果应该返回一个数字:7,因为"mozilla"的长度为7个字符. 说字符串的长度有用是有很多原因的, 例如,你可能想算出一连串名字的长度,并用名字长度来作为名字排序的依据,亦或让一个用户知道他输入的用户名太长,已经超出了输入的字符串长度限制。

+ +

检索特定字符串字符

+ +

在相关的注释中,您可以使用方括号表示法返回字符串中的任何字符 - 这意味着您可以在变量名的末尾包含方括号([ ])。 在方括号内,您可以包含要返回的字符的编号,例如,您要检索第一个字母,可以这样做:

+ +
browserType[0];
+ +

电脑从0开始,不是1! 要检索任何字符串的最后一个字符,我们可以使用下面这行,将这种技术与我们上面看到的length属性相结合起来:

+ +
browserType[browserType.length-1];
+ +

“mozilla”的长度为7,但由于计数从0开始,所以字符位置为6,因此需要长度为length-1。 例如,您可以使用它来查找一系列字符串的第一个字母,并按字母顺序排列。

+ +

在字符串中查找子字符串并提取它

+ +
    +
  1. 有时候你会想要找出一个较小的字符串是否存在于一个较大的字符串中(我们通常会说一个字符串中存在一个子字符串)。 这可以使用{{jsxref("String.prototype.indexOf()","indexOf()")}}方法来完成,该方法需要一个{{glossary("parameter")}} — 你想要搜索的子字符串。 尝试以下: +
    browserType.indexOf('zilla');
    + 结果是2,因为子字符串“zilla”从“mozilla”内的位置2(0,1,2 —— 所以从第3个字符)开始。 这样的代码可以用来过滤字符串。 例如,假设我们有一个Web地址列表,但我们只想打印出包含“mozilla”的那些地址。
  2. +
+ +
    +
  1. 这可以用另一种可能更有效的方式来实现。 尝试以下: +
    browserType.indexOf('vanilla');
    + 这应该会得到 -1 的结果 —— 当在主字符串中找不到子字符串(在本例中为“vanilla”)时将返回 -1
    +
    + 您可以使用它来查找不包含子串“mozilla”的所有字符串实例,或者如果使用否定运算符,请执行以下操作。 你可以这样做: +
    if(browserType.indexOf('mozilla') !== -1) {
    +  // do stuff with the string
    +}
    +
  2. +
  3. 当你知道字符串中的子字符串开始的位置,以及想要结束的字符时,{{jsxref("String.prototype.slice()", "slice()")}}可以用来提取 它。 尝试以下: +
    browserType.slice(0,3);
    + 这时返回"moz"——第一个参数是开始提取的字符位置,第二个参数是提取的最后一个字符的后一个位置。所以提取从第一个位置开始,直到但不包括最后一个位置。(此例中)你也可以说第二个参数等于被返回的字符串的长度。
    +  
  4. +
  5. 此外,如果您知道要在某个字符之后提取字符串中的所有剩余字符,则不必包含第二个参数,而只需要包含要从中提取的字符位置 字符串中的其余字符。 尝试以下: +
    browserType.slice(2);
    + 这返回“zilla” —— 这是因为2的字符位置是字母z,并且因为没有包含第二个参数,所以返回的子字符串是字符串中的所有剩余字符。
  6. +
+ +
+

Note: slice()的第二个参数是可选的 :如果没有传入这个参数,分片结束位置会在原始字符串的末尾。这个方法也有其他的选项;学习{{jsxref("String.prototype.slice()", "slice()")}}这页,来看看你还能发现什么其他作用。

+
+ +

转换大小写

+ +

字符串方法{{jsxref("String.prototype.toLowerCase()","toLowerCase()")}}和{{jsxref("String.prototype.toUpperCase()","toUpperCase()")}}字符串并将所有字符分别转换为小写或大写。 例如,如果要在将数据存储在数据库中之前对所有用户输入的数据进行规范化,这可能非常有用。

+ +

让我们尝试输入以下几行来看看会发生什么:

+ +
let radData = 'My NaMe Is MuD';
+radData.toLowerCase();
+radData.toUpperCase();
+ +

替换字符串的某部分

+ +

您可以使用{{jsxref("String.prototype.replace()","replace()")}}方法将字符串中的一个子字符串替换为另一个子字符串。在基础的层面上, 这个工作非常简单。你当然可以用它做一些更高级的事情,但目前我们不会涉及到。

+ +

它需要两个参数 - 要被替换下的字符串和要被替换上的字符串。 尝试这个例子:

+ +
browserType.replace('moz','van');
+ +

注意,在实际程序中,想要真正更新 browserType 变量的值,您需要设置变量的值等于刚才的操作结果;它不会自动更新子串的值。所以事实上你需要这样写:browserType = browserType.replace('moz','van');

+ +

主动学习的示例

+ +

在本节中,我们会让您尽力编写一些字符串操作代码。 在下面的每个练习中,我们有一个字符串数组,一个循环,用于处理数组中的每个值,并将其显示在项目符号列表中。 您现在不需要了解数组或循环 - 这些将在以后的文章中解释。 所有你需要做的每一种情况都是写出将以我们想要的格式输出字符串的代码。

+ +

每个示例都附带一个“重置”按钮,您可以使用该按钮重置代码,如果您犯了错误,并且无法再次工作,并且显示解决方案按钮,您可以按下来看到一个潜在的答案,如果你真的卡住了。

+ +

过滤问候留言

+ +

在第一个练习中,我们将简单介绍一下 - 我们有一系列的问候卡片消息,但我们希望对它们进行排序,以列出圣诞消息。 我们希望您在 if(...) 结构中填写条件测试,以测试每个字符串,并将其打印在列表中,如果它是圣诞消息。

+ +
    +
  1. 首先考虑一下如何测试每种情况下的消息是否为圣诞消息。 所有这些消息中都有什么字符串,您可以使用什么方法来测试是否存在?
  2. +
  3. 然后,您需要编写 操作数1 操作符 操作数2 形式的条件测试。 左边的东西等于右边的东西吗? 或者在这种情况下,方法调用在左边返回的结果在右边?
  4. +
  5. 提示:在这种情况下,测试方法调用是否不等于某个结果可能更有用。
  6. +
+ + + +

{{ EmbedLiveSample('Playable_code', '100%', 490) }}

+ +

大写修正

+ +

在这个练习中,我们有英国城市的名字,但是这个大写字母都搞砸了。 我们希望你改变它们,使它们都是小写字母,除了首字母。 一个很好的方法是:

+ +
    +
  1. 将输入变量中包含的整个字符串转换为小写,并将其存储在新变量中。
  2. +
  3. 在此新变量中获取字符串的第一个字母并将其存储在另一个变量中。
  4. +
  5. 将此最新变量用作子字符串,将小写字符串的第一个字母从小写更改为大写。 将此替换过程的结果存储在另一个新变量中。
  6. +
  7. result 变量的值与最终结果相等,而不是使用 input 变量。
  8. +
+ +
+

Note: 一个提示 - 字符串方法的参数不必是字符串文字; 它们也可以是变量,甚至是在其上调用方法的变量。

+
+ + + +

{{ EmbedLiveSample('Playable_code_2', '100%', 450) }}

+ +

从原先部分得到新字符串

+ +

在最后一个练习中,阵列包含一堆字符串,其中包含有关英格兰北部火车站的信息。 字符串是包含三字母站代码的数据项,后面是一些机器可读数据,后跟分号,后跟可读站名。 例如:

+ +
MAN675847583748sjt567654;Manchester Piccadilly
+ +

我们要提取站点代码和名称,并将它们放在一起,具有以下结构的字符串:

+ +
MAN: Manchester Piccadilly
+ +

我们建议这样做:

+ +
    +
  1. 提取三个字母的站代码并将其存储在一个新的变量中。
  2. +
  3. 查找分号的字符索引号。
  4. +
  5. 使用分号字符索引号作为参考点提取人可读的站名,并将其存储在新变量中。
  6. +
  7. 连接两个新的变量和一个字符串文字,使最终的字符串。
  8. +
  9. result 变量的值更改为等于最终的字符串,而不是 input
  10. +
+ + + +

{{ EmbedLiveSample('Playable_code_3', '100%', 485) }}

+ +

结论

+ +

你不能逃避的事实是在编程中处理单词和句子是非常重要的——特别是在JavaScript中,因为网站都是关于与人沟通的。 本文已经给出了您现在需要了解的关于操作字符串的基础知识。这将在未来进入更复杂的主题时为您服务。 接下来,我们将在短期内研究我们需要关注的最后一个主要的数据类型——数组。

+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}

diff --git a/files/zh-cn/learn/javascript/first_steps/variables/index.html b/files/zh-cn/learn/javascript/first_steps/variables/index.html new file mode 100644 index 0000000000..3ba4e02f60 --- /dev/null +++ b/files/zh-cn/learn/javascript/first_steps/variables/index.html @@ -0,0 +1,431 @@ +--- +title: 如何存储你需要的信息 — 变量 +slug: Learn/JavaScript/First_steps/Variables +tags: + - 初始化 + - 变量 + - 声明 + - 字符串 + - 数组 +translation_of: Learn/JavaScript/First_steps/Variables +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps")}}
+ +

在读完之前的一些文章之后,你现在应该大概知道了JavaScript是什么,你能用它干什么,它是怎么跟其他web技术(HTML,CSS)协同工作的,以及它有哪些主要特性。在本章节,我们将开始学习JavaScript的基础,了解如何使用 -- 变量。

+ + + + + + + + + + + + +
预备知识:电脑基础知识,了解基本的 HTML 和 CSS,了解JavaScript是什么。
目标:熟悉JavaScript的变量使用
+ +

需要的工具

+ +

在本章中,你将要输入一些代码来测试你对相关内容的理解。如果你是用的桌面浏览器,输入这些代码最好的地方是浏览器的JavaScript终端,(参考 什么是浏览器开发工具 查看如何使用这些工具)。

+ +

当然,我们也提供了一个简单的JavaScript终端,嵌入在下文的页面中,以便你更容易的输入和测试这些代码。

+ +

变量是什么?

+ +

一个变量,就是一个用于存放数值的容器。这个数值可能是一个用于累加计算的数字,或者是一个句子中的字符串。变量的独特之处在于它存放的数值是可以改变的。让我们看一个简单的例子:

+ +
<button>Press me</button>
+ +
const button = document.querySelector('button');
+
+button.onclick = function() {
+  let name = prompt('What is your name?');
+  alert('Hello ' + name + ', nice to see you!');
+}
+ +

{{ EmbedLiveSample('变量是什么', '100%', 50, "", "", "hide-codepen-jsfiddle") }}

+ +

在上面的例子中,点击按钮之后,第一行代码会在屏幕上弹出一个对话框,让你输入名字,然后存储输入的名字到一个变量。第二行代码将会显示包含你名字的欢迎信息,你的名字就是从之前的变量里面读取的。

+ +

为了理解变量的作用,我们可以思考一下,如果不使用变量,我们实现上述功能的代码将是这样的:

+ +
let name = prompt('What is your name?');
+
+if (name === 'Adam') {
+  alert('Hello Adam, nice to see you!');
+} else if (name === 'Alan') {
+  alert('Hello Alan, nice to see you!');
+} else if (name === 'Bella') {
+  alert('Hello Bella, nice to see you!');
+} else if (name === 'Bianca') {
+  alert('Hello Bianca, nice to see you!');
+} else if (name === 'Chris') {
+  alert('Hello Chris, nice to see you!');
+}
+
+// ... and so on ...
+ +

你可能暂时还没有完全理解这些代码和语法,但是你应该能够理解到 -- 如果我们没有变量,我们就不得不写大量的代码去枚举和检查输入的名字,然后去显示它们。这样做显然是低效率和不可行的 -- 你没有办法列举出所有可能的输入。

+ +

变量的另一个特性就是它们能够存储任何的东西 -- 不只是字符串和数字。变量可以存储更复杂的数据,甚至是函数。你将在后续的内容中体验到这些用法。

+ +

我们说,变量是用来存储数值的,那么有一个重要的概念需要区分。变量不是数值本身,它们仅仅是一个用于存储数值的容器。你可以把变量想象成一个个用来装东西的纸箱子。

+ +

+ +

声明变量

+ +

要想使用变量,你需要做的第一步就是创建它 -- 更准确的说,是声明一个变量。声明一个变量的语法是在 varlet 关键字之后加上这个变量的名字:

+ +
let myName;
+let myAge;
+ +

在这里我们声明了两个变量 myNamemyAge. 那么现在尝试输入这些代码到你的浏览器终端或者下面提供的JavaScript终端 (你也可以在另一个独立的标签页或窗口 open this consol ). 此外,你也可以多声明几个变量.

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300, "", "", "hide-codepen-jsfiddle") }}

+ +
+

提示: 在JavaScript中,所有代码指令都会以分号结尾 (;) — 如果忘记加分号,你的单行代码可能执行正常,但是在多行代码在一起的时候就可能出错。所以,最好是养成主动以分号作为代码结尾的习惯。

+
+ +

你可以通过使用变量的方式来验证这个变量的数值是否在执行环境中已经存在。例如,

+ +
myName;
+myAge;
+ +

以上这两个变量并没有数值,他们是空的容器。当你输入变量名并回车后,你会得到一个undefined的返回值。如果他们并不存在的话,那你就会得到一个报错信息。不信的话,可以尝试输入:

+ +
scoobyDoo;
+ +
+

提示: 千万不要把两个概念弄混淆了,“一个变量存在,但是没有数值”和“一个变量并不存在” — 他们完全是两回事 — 在前面你看到的盒子的类比中,不存在意味着没有可以存放变量的“盒子”。没有定义的值意味着有一个“盒子”,但是它里面没有任何值。

+
+ +

初始化变量

+ +

一旦你定义了一个变量,你就能够初始化它. 方法如下,在变量名之后跟上一个“=”,然后是数值:

+ +
myName = 'Chris';
+myAge = 37;
+ +

现在回到控制台并且尝试输入这几行。每输入一条你都应该确认一下控制台输出的变量是不是你刚赋的值。 同样,你可以通过在控制台中输入变量的名称来返回该变量的值 — 再次尝试下这些:

+ +
myName;
+myAge;
+ +

你可以像这样在声明变量的时候给变量初始化:

+ +
let myName = 'Chris';
+ +

这可能是大多数时间你都会使用的方式, 因为它要比在单独的两行上做两次操作要快。

+ +
+

Note: 如果你写一个声明和初始化变量的多行JavaScript代码的程序,你可以在初始化变量之后再实际声明它,并且它仍然可以工作。这是因为变量的声明通常在其余的代码执行之前完成。这叫做顶置—阅读var hoisting来了解更多细节。

+
+ +

var 与 let 的区别

+ +

此时,您可能会想:“为什么我们需要两个关键字来定义变量?”,“为什么有 varlet 呢?"。

+ +

原因是有些历史性的。 回到最初创建 JavaScript 时,是只有 var 的。 在大多数情况下,这种方法可以接受, 但有时在工作方式上会有一些问题——它的设计会令人困惑或令人讨厌 。 因此,let 是在现代版本中的 JavaScript 创建的一个新的关键字,用于创建与 var 工作方式有些不同的变量,解决了过程中的问题。

+ +

下面解释几个简单的差异。 我们现在不会讨论所有的差异,但是当您了解有关 JavaScript 的更多信息时,您将开始发现它们(如果您现在真的想要阅读它们,请随时查看我们的参考页面)。

+ +

首先,如果你编写一个声明并初始化变量的多行 JavaScript 程序,你可以在初始化一个变量之后用 var 声明它,它仍然可以工作。 例如:

+ +
myName = 'Chris';
+
+function logName() {
+  console.log(myName);
+}
+
+logName();
+
+var myName;
+ +
+

Note: 只有在 web 文档中运行多行 JavaScript 时才会有这种效果,当在 JavaScript 控制台中键入单独的行,这将不起作用。

+
+ +

这是由于变量的提升,更多细节请阅读变量提升

+ +

但提升操作不再适用于 let 。如果将上面例子中的 var 替换成 let 将不起作用并引起一个错误。 这是一件好事——因为初始化后再声明一个变量会使代码变得混乱和难以理解。

+ +

其次,当你使用 var 时,可以根据需要多次声明相同名称的变量,但是 let 不能。 以下将有效:

+ +
var myName = 'Chris';
+var myName = 'Bob';
+ +

但是以下内容会在第二行引发错误:

+ +
let myName = 'Chris';
+let myName = 'Bob';
+ +

你必须这样做:

+ +
let myName = 'Chris';
+myName = 'Bob';
+ +

同样,这是一个明智的语言决定。没有理由重新声明变量——这只会让事情变得更加混乱。

+ +

出于这些以及其他原因,我们建议您在代码中尽可能多地使用 let,而不是 var。因为没有理由使用 var,除非您需要用代码支持旧版本的 Internet Explorer (它直到第 11 版才支持 let ,现代的 Windows Edge 浏览器支持的很好)。

+ +
+

  Note: 我们目前正在更新课程以使用let而不是var。 忍耐一下!

+
+ +

更新变量

+ +

一旦变量赋值,您可以通过简单地给它一个不同的值来更新它。试试在你的控制台中输入下面几行:

+ +
myName = 'Bob';
+myAge = 40;
+ +

关于变量命名的规则

+ +

你可以给你的变量赋任何你喜欢的名字,但有一些限制。 一般你应当坚持使用拉丁字符(0-9,a-z,A-Z)和下划线字符。

+ + + +
+

Note: 你能从词汇语法—关键字找到一个相当完整的保留关键字列表来避免使用关键字当作变量。

+
+ +

好的命名示例:

+ +
age
+myAge
+init
+initialColor
+finalOutputValue
+audio1
+audio2
+ +

错误与差的命名示例:

+ +
1
+a
+_12
+myage
+MYAGE
+var
+Document
+skjfndskjfnbdskjfb
+thisisareallylongstupidvariablenameman
+ +

现在尝试创建更多的变量,请将上面的指导铭记于心。

+ +

变量类型

+ +

可以为变量设置不同的数据类型。本节我们将对其进行简短的介绍,在以后的文章中,你会更详细地了解它们。

+ +

到目前为止我们已经认识了前2个,但是还有其他的。

+ +

Number

+ +

你可以在变量中存储数字,不论这些数字是像30(也叫整数)这样,或者像2.456这样的小数(也叫做浮点数)。与其他编程语言不同,在 JavaScript 中你不需要声明一个变量的类型。当你给一个变量数字赋值时,不需要用引号括起来。 

+ +
let myAge = 17;
+ +

String

+ +

字符串是文本的一部分。当你给一个变量赋值为字符串时,你需要用单引号或者双引号把值给包起来,否则JavaScript将会把这个字符串值理解成别的变量名。

+ +
let dolphinGoodbye = 'So long and thanks for all the fish';
+ +

Boolean

+ +

Boolean 的值有2种:true或false。它们通常被用于在适当的代码之后,测试条件是否成立。举个例子,一个简单的示例如下: 

+ +
let iAmAlive = true;
+ +

然而实际上通常是以下用法:

+ +
let test = 6 < 3;
+ +

这是使用“小于”操作符(<)来测试6小于3。正如你所料的,将会返回false,因为6并不小于3!在这个课程中,以后你将会学到许多有关操作符的知识。

+ +

Array

+ +

数组是一个单个对象,其中包含很多值,方括号括起来,并用逗号分隔。尝试在您的控制台输入以下行:

+ +
let myNameArray = ['Chris', 'Bob', 'Jim'];
+let myNumberArray = [10,15,40];
+ +

当数组被定义后,您可以使用如下所示的语法来访问各自的值,例如下行:

+ +
myNameArray[0]; // should return 'Chris'
+myNumberArray[2]; // should return 40
+ +

此处的方括号包含一个索引值,该值指定要返回的值的位置。 您可能已经注意到,计算机从0开始计数,而不是像我们人类那样的1。

+ +

在以后的文章,你将更多地了解数组。

+ +

Object

+ +

在编程中,对象是现实生活中的模型的一种代码结构。您可以有一个简单的对象,代表一个停车场,并包含有关其宽度和长度的信息,或者您可以有一个代表一个人的对象,并包含有关他们的名字,身高,体重,他们说什么语言,如何说 你好,他们,等等。

+ +

尝试在您的控制台输入以下行:

+ +
let dog = { name : 'Spot', breed : 'Dalmatian' };
+ +

要检索存储在对象中的信息,可以使用以下语法:

+ +
dog.name
+ +

我们现在不会看对象了 - 您可以在将来的模块中了解更多关于这些对象的信息.

+ +

动态类型

+ +

JavaScript是一种“动态类型语言”,这意味着不同于其他一些语言(译者注:如C、JAVA),您不需要指定变量将包含什么数据类型(例如number或string)

+ +

例如,如果你声明一个变量并给它一个带引号的值,浏览器就会知道它是一个字符串:

+ +
let myString = 'Hello';
+ +

即使它包含数字,但它仍然是一个字符串,所以要小心:

+ +
let myNumber = '500'; // oops, this is still a string
+typeof myNumber;
+myNumber = 500; // much better — now this is a number
+typeof myNumber
+ +

尝试依次将上述代码输入您的控制台,看看结果是什么(无须输入//之后的注释)。 我们使用了一个名为typeof的特殊的操作符 ——它会返回所传递给它的变量的数据类型。 第一次在上面的代码中调用它,它应该返回string,因为此时myNumber变量包含一个字符串'500'。 看看它第二次将返回什么。

+ +

总结

+ +

到目前为止,您应该了解了一些JavaScript变量以及如何创建它们。 在下一篇文章中,我们将更详细地关注数字,了解如何在JavaScript中使用基础数学。

+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps")}}

+ +

在此模块内

+ + diff --git a/files/zh-cn/learn/javascript/first_steps/what_is_javascript/index.html b/files/zh-cn/learn/javascript/first_steps/what_is_javascript/index.html new file mode 100644 index 0000000000..b62daa5a1d --- /dev/null +++ b/files/zh-cn/learn/javascript/first_steps/what_is_javascript/index.html @@ -0,0 +1,501 @@ +--- +title: 什么是 JavaScript? +slug: Learn/JavaScript/First_steps/What_is_JavaScript +tags: + - API + - JavaScript + - 初学者 + - 核心 + - 浏览器 +translation_of: Learn/JavaScript/First_steps/What_is_JavaScript +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps")}}
+ +

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

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

广义的定义

+ +

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

+ +

+ + + +

这三层依次建立,秩序井然。以文本标签(text label)的简单示例。首先用 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;
+}
+ + + +

{{ EmbedLiveSample('Beautiful_name_label', '100%', 80, "", "", "hide-codepen-jsfiddle") }}

+ +

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

+ +
const para = document.querySelector('p');
+
+para.addEventListener('click', updateName);
+
+function updateName() {
+  let name = prompt('输入一个新的名字:');
+  para.textContent = '玩家1:' + name;
+}
+
+ + + +

{{ EmbedLiveSample('Customizable_name_label', '100%', 80, "", "", "hide-codepen-jsfiddle") }}

+ +

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

+ +

JavaScript 能做的远不止这些。让我们来仔细探索。

+ +

它到底可以做什么?

+ +

客户端(client-side)JavaScript 语言的核心包含一些普遍的编程特性,以让你可以做到如下的事情:

+ + + +

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

+ +

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

+ +

API 通常分为两类。

+ +

+ +

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

+ + + +
+

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

+
+ +

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

+ + + +
+

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

+
+ +

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

+ +

JavaScript 在页面上做了什么?

+ +

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

+ +

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

+ +

+ +

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

+ +

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

+ +

浏览器安全

+ +

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

+ +
+

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

+
+ +

JavaScript 运行次序

+ +

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

+ +
const para = document.querySelector('p');
+
+para.addEventListener('click', updateName);
+
+function updateName() {
+  let name = prompt('输入一个新的名字:');
+  para.textContent = '玩家1:' + name;
+}
+ +

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

+ +

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

+ +
+

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

+
+ +

解释代码 vs 编译代码

+ +

作为程序员,你或许听说过这两个术语:解释(interpret)编译(compile)。在解释型语言中,代码自上而下运行,且实时返回运行结果。代码在由浏览器执行前,不需要将其转化为其他形式。代码将直接以文本格式(text form)被接收和处理。

+ +

相对的,编译型语言需要先将代码转化(编译)成另一种形式才能运行。比如 C/C++ 先被编译成汇编语言,然后才能由计算机运行。程序将以二进制的格式运行,这些二进制内容是由程序源代码产生的。

+ +

JavaScript 是轻量级解释型语言。浏览器接受到JavaScript代码,并以代码自身的文本格式运行它。技术上,几乎所有 JavaScript 转换器都运用了一种叫做即时编译(just-in-time compiling)的技术;当 JavaScript 源代码被执行时,它会被编译成二进制的格式,使代码运行速度更快。尽管如此,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 使用 {{htmlelement("link")}} 元素链接外部样式表,使用 {{htmlelement("style")}} 元素向 HTML 嵌入内部样式表,JavaScript 这里只需一个元素——{{htmlelement("script")}}。我们来看看它是怎么工作的。

+ +

内部 JavaScript

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

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

+
+ +
+

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

+
+ +

外部 JavaScript

+ +

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

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

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

+
+ +

内联 JavaScript 处理器

+ +

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

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

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

+ + + +

{{ EmbedLiveSample('Inline_JavaScript', '100%', 150, "", "", "hide-codepen-jsfiddle") }}

+ +

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

+ +

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

+ +

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

+ +
const buttons = document.querySelectorAll('button');
+
+for(let i = 0; i < buttons.length ; i++) {
+  buttons[i].addEventListener('click', createParagraph);
+}
+ +

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

+ +
+

:请尝试修改 apply-javascript.html 以添加更多按钮。刷新后可发现按下任一按钮时都会创建一个段落。很高效吧。

+
+ +

脚本调用策略

+ +

要让脚本调用的时机符合预期,需要解决一系列的问题。这里看似简单,实际大有文章。最常见的问题就是:HTML 元素是按其在页面中出现的次序调用的,如果用 JavaScript 来管理页面上的元素(更精确的说法是使用 文档对象模型 DOM),若 JavaScript 加载于欲操作的 HTML 元素之前,则代码将出错。

+ +

在上文的“内部”、“外部”示例中,JavaScript 调用于文档头处,解析 HTML 文档体之前。这样做是有隐患的,需要使用一些结构来避免错误发生。

+ +

“内部”示例使用了以下结构:

+ +
document.addEventListener("DOMContentLoaded", function() {
+  . . .
+});
+ +

这是一个事件监听器,它监听浏览器的 "DOMContentLoaded" 事件,即 HTML 文档体加载、解释完毕事件。事件触发时将调用 " . . ." 处的代码,从而避免了错误发生(事件 的概念稍后学习)。

+ +

“外部”示例中使用了 JavaScript 的一项现代技术(async “异步”属性)来解决这一问题,它告知浏览器在遇到 <script> 元素时不要中断后续 HTML 内容的加载。

+ +
<script src="script.js" async></script>
+ +

上述情况下,脚本和 HTML 将一并加载,代码将顺利运行。

+ +
+

:“外部”示例中 async 属性可以解决调用顺序问题,因此无需使用 DOMContentLoaded 事件。而 async 只能用于外部脚本,因此不适用于“内部”示例。

+
+ +

解决此问题的旧方法是:把脚本元素放在文档体的底端(</body> 标签之前,与之相邻),这样脚本就可以在 HTML 解析完毕后加载了。此方案(以及上述的 DOMContentLoaded 方案)的问题是:只有在所有 HTML DOM 加载完成后才开始脚本的加载/解析过程。对于有大量 JavaScript 代码的大型网站,可能会带来显著的性能损耗。这也是 async 属性诞生的初衷。

+ +

asyncdefer

+ +

上述的脚本阻塞问题实际有两种解决方案 —— asyncdefer。我们来依次讲解。

+ +

浏览器遇到 async 脚本时不会阻塞页面渲染,而是直接下载然后运行。这样脚本的运行次序就无法控制,只是脚本不会阻止剩余页面的显示。当页面的脚本之间彼此独立,且不依赖于本页面的其它任何脚本时,async 是最理想的选择。

+ +

比如,如果你的页面要加载以下三个脚本:

+ +
<script async src="js/vendor/jquery.js"></script>
+
+<script async src="js/script2.js"></script>
+
+<script async src="js/script3.js"></script>
+ +

三者的调用顺序是不确定的。jquery.js 可能在 script2script3 之前或之后调用,如果这样,后两个脚本中依赖 jquery 的函数将产生错误,因为脚本运行时 jquery 尚未加载。

+ +

解决这一问题可使用 defer 属性,脚本将按照在页面中出现的顺序加载和运行:

+ +
<script defer src="js/vendor/jquery.js"></script>
+
+<script defer src="js/script2.js"></script>
+
+<script defer src="js/script3.js"></script>
+ +

添加 defer 属性的脚本将按照在页面中出现的顺序加载,因此第二个示例可确保 jquery.js 必定加载于 script2.jsscript3.js 之前,同时 script2.js 必定加载于 script3.js 之前。

+ +

脚本调用策略小结:

+ + + +

注释

+ +

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

+ + + +

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

+ +
// 函数:创建一个新的段落并添加至 HTML body 底部。
+function createParagraph() {
+  let para = document.createElement('p');
+  para.textContent = '你点了这个按钮!';
+  document.body.appendChild(para);
+}
+
+/*
+  1. 取得页面上所有按钮的引用并将它们置于一个数组中。
+  2. 通过一个循环为每个按钮添加一个点击事件的监听器。
+  当按钮被点击时,调用 createParagraph() 函数。
+*/
+
+const buttons = document.querySelectorAll('button');
+
+for (let i = 0; i < buttons.length; i++) {
+  buttons[i].addEventListener('click', createParagraph);
+}
+ +

小结

+ +

恭喜你,迈出了探索 JavaScript 世界的第一步。我们从理论开始,介绍为什么要使用 JavaScript,以及用它能做什么事情。过程中穿插了一些代码示例并讲解了 JavaScript 如何与网站中其他代码适配,等等。

+ +

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

+ +

{{NextMenu("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps")}}

+ +

本章目录

+ + + +

+ +

diff --git a/files/zh-cn/learn/javascript/first_steps/what_went_wrong/index.html b/files/zh-cn/learn/javascript/first_steps/what_went_wrong/index.html new file mode 100644 index 0000000000..b36d8be3df --- /dev/null +++ b/files/zh-cn/learn/javascript/first_steps/what_went_wrong/index.html @@ -0,0 +1,284 @@ +--- +title: 查找并解决 JavaScript 代码的错误 +slug: Learn/JavaScript/First_steps/What_went_wrong +tags: + - JavaScript + - 初学者 + - 开发者工具 + - 指导教程 + - 文章 + - 调试 + - 错误 +translation_of: Learn/JavaScript/First_steps/What_went_wrong +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps")}}
+ +

上一节中你创建了“猜数字”游戏,但它可能没有正常工作。别担心,本节将为你提供一些简单的提示,来帮助你查找并修复JavaScript程序中的错误,从而让你远离困扰。

+ + + + + + + + + + + + +
预备知识:计算机基础知识,初步理解HTML和CSS,了解JavaScript。
目标:获得独立修复简单问题的能力和信心。
+ +

错误类型

+ +

一般来说,代码错误主要分为两种:

+ + + +

事情远没有你想的那么简单,随着探究的深入,会有更多差异因素浮出水面。但在编程生涯的初级阶段上述分类方法已足矣。下面我们将依次分析。

+ +

一个出错的示例

+ +

让我们重回猜数字游戏,这次我们将故意引入一些错误。请到Github下载一份 number-game-errors.html (或 在线运行)。

+ +
    +
  1. 请分别在你的文本编辑器和浏览器中打开刚下载的文件。
  2. +
  3. 先试玩游戏,你会发现在点击“确定”按钮时,游戏并没有响应。
  4. +
+ +
+

:你可能还在为修复你自己版本的游戏头疼,但我们仍然希望你先用我们的版本来完成这一节,这样你才能学到本节中的技术。然后再去修复自己的游戏也不晚。

+
+ +

首先查看开发者控制台,看是否存在语法错误,然后尝试修复。详见下文。

+ +

修复语法错误

+ +

以前的课程中,你学会了在 开发工具 JavaScript 控制台 中输入一些简单的 JavaScript 命令。(如果你忘记了如何在浏览器中打开它,可以直接打开上面的链接)。更实用的是,当 JavaScript 代码进入浏览器的 JavaScript 引擎时,如果存在语法错误,控制台会提供出错信息。现在我们去看一看。

+ +
    +
  1. +

    打开 number-game-errors.html 所在的标签页,然后打开 JavaScript 控制台。你将看到以下出错信息:

    + 不是函数
  2. +
  3. 这个错误很容易跟踪,浏览器为你提供了几条有用的信息(截图来自 Firefox,其他浏览器也提供类似信息)。从左到右依次为:
  4. +
+ + + +
    +
  1. 我们在代码编辑器中找到第 86 行:
  2. +
+ +
guessSubmit.addeventListener('click', checkGuess);
+ +
    +
  1. 出错信息显示“guessSubmit.addeventListener 不是一个函数”,说明这里可能存在拼写错误。如果你不确定某语法的拼写是否正确,可以到 MDN 上去查找,目前最简便的方法就是去你喜欢的搜索引擎搜索“MDN + 语言特性”。就本文当前内容你可以点击addEventListener()
  2. +
  3. 因此这里错误显然是我们把函数名写错造成的。请记住,JavaScript 区分大小写,所以任何轻微的不同或大小写问题都会导致出错。将 addeventListener 改为 addEventListener 便可解决。
  4. +
+ +
+

注:更多信息请参考 类型错误:“x”不是一个函数

+
+ +

语法错误:第二轮

+ +
    +
  1. 保存页面并刷新,可以看到出错信息不见了。
  2. +
  3. 现在,如果尝试输入一个数字并按确定按钮,你会看到...另一个错误!
  4. +
  5. 此次出错信息为“TypeError:lowOrHi is null”(“类型错误:lowOrHi为null”),在第 78 行。 +
    Null是一个特殊值,意思是“什么也没有”,或者“没有值”。这表示 lowOrHi 已声明并初始化,但没有任何有意义的值,可以说:它没有类型没有值。
    + +
    :这条错误没有在页面加载时立即发生,是因为它发生在函数内部(checkGuess() { ... }块中)。函数内部的代码运行于一个外部代码相互独立的域内,后面函数的文章中将更详细地讲解。此时此刻,只有当代码运行至86行并调用 checkGuess() 函数时,代码才会抛出出错信息。
    +
  6. +
  7. 请观察第 78 行代码: +
    lowOrHi.textContent = '你猜高了!';
    +
  8. +
  9. 该行试图将 lowOrHi 变量中的 textContent 属性设置为一个字符串,但是失败了,这是因为 lowOrHi 并不包含预期的内容。为了一探究竟,你可以在代码中查找一下该变量的的其他实例。lowOrHi 最早出现于第 48 行: +
    const lowOrHi = document.querySelector('lowOrHi');
    +
  10. +
  11. 此处,我们试图让该变量包含一个指向文档 HTML 中特定元素的引用。我们来检查一下在该行代码执行后变量的值是否为 null。在第 49 行添加以下代码: +
    console.log(lowOrHi);
    + +
    +

    console.log() 是一个非常实用的调试功能,它可以把值打印到控制台。因此我们将其置于代码第 48 行时,它会将 lowOrHi 的值打印至控制台。

    +
    +
  12. +
  13. 保存并刷新,你将在控制台看到 console.log() 的执行结果: 显然,此处 lowOrHi 的值为 null,所以第 48 行肯定有问题。
  14. +
  15. 我们来思考问题有哪些可能。第 48 行使用 document.querySelector() 方法和一个 CSS 选择器来取得一个元素的引用。进一步查看我们的文件,我们可以找到有问题的段落: +
    <p class="lowOrHi"></p>
    +
  16. +
  17. 这里我们需要一个类选择器,它应以一个点开头(.),但被传递到第 48 行的querySelector()方法中的选择器没有点。这可能是问题所在!尝试将第 48 行中的 lowOrHi 改成 .lowOrHi
  18. +
  19. 再次保存并刷新,此时 console.log() 语句应该返回我们想要的 <p> 元素。终于把错误搞定了!此时你可以把 console.log() 一行删除,或保留它以便随后参考。选择权在你。
  20. +
+ +
+

:此错误的更多详细信息请参阅:类型错误:“x”(不)是“y”

+
+ +

语法错误:第三轮

+ +
    +
  1. 现在,如果你再次试玩,你离成功更进了一步。游戏过程按部就班,直到猜测正确或机会用完,游戏结束。
  2. +
  3. 此时如果点击“开始新游戏”,游戏将再次出错,抛出与开始时同样的错误——“TypeError:resetButton.addeventListener is not a function”!这次它来自第 94 行。
  4. +
  5. 查看第 94 行,很容易看到我们犯了同样的错误。我们只需要再次将 addeventListener 改为 addEventListener。现在就改吧。
  6. +
+ +

逻辑错误

+ +

此时,游戏应该可以顺利进行了。但经过几次试玩后你一定会注意到要猜的随机数不是 0 就是 1。这可不是我们期望的!

+ +

游戏的逻辑肯定是哪里出现了问题,因为游戏并没有返回错误,只是不能正确运行。

+ +
    +
  1. 寻找 randomNumber 变量和首次设定随机数的代码。保存着游戏开始时玩家要猜的随机数的实例大约在 44 行: + +
    let randomNumber = Math.floor(Math.random()) + 1;
    + +

    重新开始游戏产生随机数的设定语句大约在 113 行:

    + +
    randomNumber = Math.floor(Math.random()) + 1;
    +
  2. +
  3. 为了检查问题是否来自这两行,我们要再次转到我们的朋友-控制台:在两行代码之后各插入下面的代码: +
    console.log(randomNumber);
    +
  4. +
  5. 保存并刷新,然后试玩,你会看到在控制台显示的随机数总是等于1。
  6. +
+ +

修正逻辑错误

+ +

为了解决这个问题,让我们来思考这行代码如何工作。首先,我们调用 Math.random(),它生成一个在 0 和 1 之间的十进制随机数,例如 0.5675493843。

+ +
Math.random()
+
+ +

接下来,我们把调用 Math.random() 的结果作为参数传递给 Math.floor(),它会舍弃小数部分返回与之最接近的整数。然后我们给这个结果加上1:

+ +
Math.floor(Math.random()) + 1
+
+ +

由于将一个 0 和 1 之间的随机小数的小数部分舍弃,返回的整数一定为 0,因此在此基础上加 1 之后返回值一定为 1。要在舍弃小数部分之前将它乘以100。便可得到 0 到 99 之间的随机数:

+ +
Math.floor(Math.random() * 100);
+
+ +

然后再加 1,便可得到一个 100 以内随机的自然数:

+ +
Math.floor(Math.random() * 100) + 1;
+ +

将上述两行内容替换为此,然后保存刷新,游戏终于如期运行了!

+ +

其它常见错误

+ +

代码中还会遇到其他常见错误。 本节将指出其中的大部分。

+ +

SyntaxError: missing ; before statement
+ (语法错误:语句缺少分号)

+ +

这个错误通常意味着你漏写了一行代码最后的分号,但是此类错误有时候会更加隐蔽。例如如果我们把 checkGuess() 函数中的这一行 :

+ +
let userGuess = Number(guessField.value);
+
+ +

改成

+ +
let userGuess === Number(guessField.value);
+
+ +

将抛出一个错误。因为系统认为你在做其他事情。请不要把赋值运算符(=,为一个变量赋值)和严格等于运算符(===,比较两个值是否相等,返回 true/false)弄混淆。

+ +
+

注:此错误的更多详细信息请参考 SyntaxError: missing ; before statement

+
+ +

不管输入什么程序总说“你猜对了!”

+ +

这是混淆赋值和严格等于运算符的又一症状。例如我们把 checkGuess() 里的:

+ +
if (userGuess === randomNumber) {
+ +

改成

+ +
if (userGuess = randomNumber) {
+
+ +

因为条件永远返回 true,使得程序报告你猜对了。小心哦!

+ +

SyntaxError: missing ) after argument list
+ (语法错误:参数表末尾缺少括号)

+ +

这个很简单。通常意味着函数/方法调用后的结束括号忘写了。

+ +
+

注:有关此错误的更多详细信息请参考: SyntaxError: missing ) after argument list

+
+ +

SyntaxError: missing : after property id
+ (语法错误:属性ID后缺少冒号)

+ +

JavaScript 对象的形式有错时通常会导致此类错误,如果把

+ +
function checkGuess() {
+ +

写成了

+ +
function checkGuess( {
+ +

浏览器会认为我们试图将函数的内容当作参数传回函数。写圆括号时要小心!

+ +

SystaxError: missing } after function body
+ (语法错误:函数体末尾缺少花括号)

+ +

这个简单。通常意味着函数或条件结构中丢失了一个花括号。如果我们将 checkGuess() 函数末尾的花括号删除,就会得到这个错误。

+ +

SyntaxError: expected expression, got 'string'
+ (语法错误:得到一个 'string' 而非表达式)

+ +

或者

+ +

SyntaxError: unterminated string literal
+ (语法错误:字符串字面量未正常结束)

+ +

这个错误通常意味着字符串两端的引号漏写了一个。如果你漏写了字符串开始的引号,将得到第一条出错信息,这里的 'string' 将被替换为浏览器发现的意外字符。如果漏写了末尾的引号将得到第二条。

+ +

对于所有的这些错误,想想我们在实例中是如何逐步解决的。错误出现时,转到错误所在的行观察是否能发现问题所在。记住,错误不一定在那一行,错误的原因也可能和我们在上面所说的不同!

+ +
+

注: 有关这些错误的更多详细信息请参考:SyntaxError: Unexpected token 以及 SyntaxError: unterminated string literal

+
+ +

小结

+ +

我们有了能够在简单的 JavaScript 程序中除错的基础知识。解决代码中的错误并不总是那么简单,但至少本节内容可以为刚刚踏上学习之路的你节省出几个小时来补觉,同时让问题更快速得到解决。

+ +

另请参阅

+ + + +

{{PreviousMenuNext("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps")}}

+ +

本章目录

+ + -- cgit v1.2.3-54-g00ecf