JavaScript必会基础知识
我不会涵盖 JavaScript 的所有理论和概念,而是只教您该语言最重要的构建块。我们将介绍变量、数据类型、函数、对象、数组和类等内容。您还将学习如何将它们全部混合起来构建一个小而可靠的程序。
我们还将忽略 HTML、CSS 和在浏览器中使用 JavaScript。本教程仅关注 JavaScript 作为一种编程语言,并使用终端来运行代码。
本教程还为每个部分提供了练习,让您有时间练习所学内容并将知识“钻”入您的大脑。
本手册在此网页中完全免费。如果您想要本教程的 PDF 和 EPUB 版本,您可以支付少量费用。它将帮助我创建深入的 JavaScript 教程,帮助您构建完整的 Web 应用程序。
(更|多优质内|容:java567 点 c0m)
目录
1 - JavaScript 简介
为什么要学习 JavaScript
JavaScript 与 Java
2 - 如何设置您的计算机
如何安装 VSCode
如何安装 Node.js
3 - 快速控制台介绍
4 - 是时候向世界问好了!
5 - JavaScript 代码结构
声明
评论
执行流程
练习#1
6 - JavaScript 变量
变量命名
常数变量
var 关键字
练习#2
概括
7 - JavaScript 基本数据类型
JavaScript 中的字符串
JavaScript 中的数字(整数和浮点数)
JavaScript 中的布尔值
JavaScript 中未定义
JavaScript 中的空值
8 - 类型转换和强制
类型强制
类型强制规则
为什么应该避免类型强制
9 - JavaScript 中的运算符
算术运算符
赋值运算符
比较运算符
逻辑运算符
运算符的类型
练习#3
10 - JavaScript 数组
数组索引位置
数组操作的特殊方法
练习#4
11 - JavaScript 中的控制流(条件)
if...else 语句
switch...case 语句
switch 语句体
Switch 语句用例
练习#5
12 - JavaScript 中的控制流(循环)
for 语句
什么时候使用for循环?
while 语句
何时使用 while 循环?
练习#6
13 - JavaScript 中的函数
如何创建自己的函数
函数参数和参数
默认参数
默认参数和 null
返回语句
变量范围
其余参数
箭头功能
单行和多行箭头函数
不带圆括号的箭头函数
箭头函数没有参数绑定
如何轻松地将普通函数转换为箭头函数
练习#7
14 - JavaScript 中的对象
如何访问对象值
如何向对象添加新属性
如何修改对象属性
如何删除对象属性
如何检查对象中是否存在属性
练习#8
最后练习:构建一台收银机
结论
解决方案
1 - JavaScript 简介
JavaScript 是由 Brendan Eich 于 1995 年 4 月左右创建的。当时,他正在为一家名为 Netscape 的公司开发浏览器。他被告知,他只有 10 天的时间来设计和编写可在浏览器上运行的编程语言的工作原型。
他需要创建一种能够吸引非专业程序员的语言,例如 Microsoft Visual Basic。
之所以只给他 10 天的时间,是因为 Netscape 需要发布其浏览器,而该浏览器当时正在与微软竞争。
一开始,JavaScript 并不像今天那么强大,因为它最初是为网页添加交互和动画而设计的。直到 2005 年 jQuery 和 AJAX 发布后,JavaScript 才开始在每个网站中使用。
人们根本就没有一个简单的替代方法来替代 jQuery 和 AJAX 来进行 DOM 操作和发送异步请求。此外,活跃的 JavaScript 开发者社区不断向库中添加新功能。
随后,谷歌推出了现代 Chrome 浏览器,Facebook 开始吸引更多人上网。JavaScript 开始发展以适应这些互联网巨头的野心。
浏览器开始开发可以在 JavaScript 中使用的 API。JS 可以从浏览器中检索 IP 地址和地理位置等信息,从而为互联网公司提供更多能力来本地化其网站功能。
然后发生了另一项创新,使 JavaScript 变得更加强大。
2009 年发布了名为 Node.js 的服务器端环境,允许 JavaScript 像 PHP、Java、Python、Ruby 等一样在服务器端运行。它还使开发人员能够仅使用 JavaScript 开发全栈 Web 应用程序。
如今,JavaScript 是一种可以为 Web、桌面和移动应用程序提供支持的语言。
以下是 O'Reilly Media 创始人 Tim O'Reilly 的一句话:
学习 JavaScript 曾经意味着你不是一个认真的开发人员。如今,不学习 JavaScript 也意味着同样的事情。
现在,学习 JavaScript 对于那些想成为 Web 开发人员的人来说至关重要。
为什么要学习 JavaScript?
您需要学习并深入理解 JavaScript 有 4 个充分的理由:
JavaScript 是唯一可以在浏览器中运行的语言
它很容易学习(但很难掌握)
它是制作 Web 应用程序的必备语言
JavaScript 开发人员有很多职业机会
学习 JavaScript 为您提供了成为前端、后端或移动开发人员的巨大机会。
基本上,学习 JavaScript 是技术职业发展的门户。
JavaScript 与 Java
最开始,JavaScript 实际上被命名为 LiveScript。它被重命名为 JavaScript,因为 Java 是一种非常流行的编程语言。
由于大多数软件开发人员已经熟悉 Java,因此 JavaScript 这个名称被认为有助于将 JavaScript 作为一种出色的编程语言进行营销,并吸引了当时开发人员的兴趣。
需要明确的是,JavaScript 和 Java 是两种完全不同的编程语言。您无需了解 Java 即可学习 JavaScript(反之亦然)。:)
2 - 如何设置您的计算机
要使用 JavaScript 编写程序,您需要安装 2 个可用于所有操作系统的免费工具。
第一个要安装的工具是 Visual Studio Code。
如何安装 VSCode
Visual Studio Code 或简称 VSCode 是一个为编写代码而创建的文本编辑器程序。除了免费之外,VSCode 也是开源的,并且可在所有主要操作系统上使用。
您可以在 Windows、macOS 和 Linux 上使用 VSCode,因此如果您的计算机上没有文本编辑器,我建议您在此处安装 VSCode。
现在您已经有了一个文本编辑器来编写 JavaScript 代码,您还需要一个软件来运行 JavaScript 代码。接下来让我们安装 Node.js。
如何安装 Node.js
要在浏览器外部运行 JavaScript,您需要安装 Node.js,它本质上是一个 JavaScript 运行器。
只需访问 Node.js 网站 nodejs.org 并下载适合您计算机的最新 LTS 版本。下载完成后,将其安装到您的系统上。
您需要使用控制台运行 Node.js,因此打开命令行或终端应用程序并运行以下命令:
node -v
此命令会将新安装的 Node.js 的版本输出到控制台。
3 - 快速控制台介绍
控制台是一个基于文本的界面,可用于在计算机上键入和运行命令。在 Windows 上,它称为命令行。在 macOS 和 Linux 上,它称为终端。
您不会使用控制台中可用的所有命令。事实上,您只需要了解 7 个基本命令即可帮助您运行 JavaScript 代码。
首先,打开计算机上的控制台程序并输入命令pwd:
pwd
这是您用来查找终端当前所在目录的命令。pwd是打印工作目录的缩写。
要更改工作目录,您需要运行该cd命令。
下面是移动到子目录的示例:
cd directory_name/directory_name
要向上移动到父目录,请..在命令旁边指定:
cd ..
要向上移动多个目录,请使用../..
要清除控制台上以前的命令和输出,请使用以下clear命令:
clear
要打印当前目录中的文件和目录列表,请运行以下ls命令:
ls
要创建新文件,请使用以下touch命令,后跟文件名和扩展名:
touch index.js
上面的命令将创建一个index.js以当前工作目录命名的新 JavaScript 文件。
要创建新目录,请使用mkdir命令后跟目录名称:
mkdir my_project
要使用 Node.js 运行 JavaScript,请指定node后跟文件名,如下所示:
node index.js
您将在同一控制台中看到代码的所有输出。
您可以使用控制台做很多事情,但这 7 个命令就足够了,因为我们只需要它来运行 JavaScript 代码。
接下来,让我们运行您的第一个 JavaScript 程序!
4 - 是时候向世界问好了!
是时候使用 Node 运行您的第一个 JavaScript 程序了。
从控制台中,创建一个index.js使用touch以下命令命名的新 JavaScript 文件。
touch index.js
接下来,使用 VSCode 打开该文件并将以下代码行写入该文件中:
console.log("Hello World!");
返回控制台,使用 Node 运行此脚本:
node index.js
控制台应该执行该index.js文件并打印“Hello World!”。
您刚刚使用 Node.js 运行了第一个 JavaScript 程序。出色的!
当您运行该node index.js命令时,Node.js 程序开始从上到下逐行读取脚本。
程序node发现您写了单词,console.log后跟括号(),因此它知道您正在指示它打印某些内容。然后程序读取您在括号中输入的内容并将其打印在控制台上。
在 VSCode 或其他文本编辑器程序中,您应该看到代码的不同部分以不同的颜色突出显示。这是文本编辑器的一项功能,称为语法突出显示,它对于帮助您区分代码的不同部分非常有用。
关键字log是一个函数,因此它以一种颜色突出显示,而括号中的单词则具有另一种颜色。
函数只是用于执行特定任务的一段代码。该log()函数用于“打印”您放在括号内的任何内容。
另一方面,console关键字是一个对象,它是一个独立的属性,可以访问某些功能。
稍后我们将了解有关函数和对象的更多信息。现在,只需记住console.log()关键字用于将内容打印到控制台即可。
接下来,我们就开始学习JavaScript代码结构。
5 - JavaScript 代码结构
计算机程序是写在文本文件中的一系列代码段。然后,这些文本文件通过专门为运行代码而设计的软件来运行。您之前下载的Node.js软件是处理JavaScript代码的工具。
在进一步讨论之前,让我们先了解一下代码的结构。
声明
语句是计算机运行的一条指令。把它想象成一个句子,但是对于计算机来说。我们可以使用分号结束语句,;就像我们可以使用点结束句子一样.
您可以在一行中编写多个语句,但约定是每行编写一个语句:
// This is hard to read
console.log("Hello World!"); console.log("I'm learning JavaScript");
// Now it's better
console.log("Hello World!");
console.log("I'm learning JavaScript");
每个语句都是执行代码的软件需要执行的某些操作的表达式。
评论
在编程中,注释是我们用来传达文件中编写的代码上下文的文本。
要在 JavaScript 中编写注释,您需要//在注释前添加两个正斜杠,如下所示:
// This is a comment
// This is also a comment
// Below print two lines of statements
console.log("Hello World!");
console.log("I'm learning JavaScript");
语言处理器会忽略注释,因此您可以使用注释来禁用某些代码,而不必删除该代码。
下面的代码显示了如何禁用第二个打印语句:
console.log("Hello World!");
// console.log("I'm learning JavaScript");
执行流程
Node.js 等语言处理器以自上而下的方法执行语句。第一行写入的语句将在第二行之前执行,然后继续执行到最后一行:
console.log("Hello World!");
console.log("I'm learning JavaScript");
// Printing numbers
console.log(1);
console.log(2);
console.log(3);
输出:
Hello World!
I'm learning JavaScript
1
2
3
如果你想在文本之前打印数字,那么你需要将相应的console.log()行移到顶部。
练习#1
尝试在控制台上打印您的姓名、年龄和职业。
输出如下所示:
John Doe
19
Student
现在你已经了解了 JavaScript 的基本代码结构,接下来我们继续学习变量。
6 - JavaScript 变量
在解释变量是什么之前,我希望您更改在index.js文件中编写的代码。
更改该文件中的代码如下:
let message = "Hello World!"
console.log(message)
接下来,使用命令运行代码node index.js。您将看到与编写“Hello World!”时相同的输出。直接在console.log()函数内部发送消息。怎么会这样?
这是因为上面代码中写的消息是一个变量。
在编程中,变量只是您赋予值的名称,以便您稍后可以访问该值。您可以将变量视为可以标记为某个值的标签,因此您可以使用该标签来引用该值。
要声明变量,您需要键入关键字,let后跟变量名称。
代码中的第一行告诉 JavaScript 将message变量与值关联起来Hello World!:
let message = "Hello World!"
在第二行中,JavaScript 被指示打印 的值message,而这正是它所做的。
您可以通过重新分配另一个值来更改变量的值,如下所示:
message = "Hello World!"
print(message)
message = "Nice weather!"
print(message)
运行该文件,您将看到打印的两行输出:
Hello World!
Nice weather!
变量用于引用数据,以便您可以在程序中多次使用相同的数据。
接下来,让我们看看 JavaScript 中变量命名的一些规则。
变量命名
JavaScript 有一些命名规则,您需要了解这些规则以避免命名错误。
变量名只能包含字母、数字和下划线( _)。这意味着您可以将变量命名为message, message_1, message_2。
变量名称的第一个字符不能是数字。message_1没关系。1_message不是。
您不能使用保留关键字,因为consoleJavaScript 使用它们来执行某些操作。JavaScript 使用了许多其他关键字,您将在以下部分中了解这些关键字,例如if、for和while。
变量名称区分大小写,这意味着Message、MESSAGE、 和message可用于创建三个不同的变量。但当然,我不建议使用相似的名称,因为这会引起混乱。
有时,您需要多个单词来声明变量名。JavaScript 有两种全球通用的命名约定:
camelCase
snake_case
驼峰式命名约定是使用大写字母作为后续单词的第一个字符。这是一个例子:
let myAwesomeVariable
蛇形命名约定使用下划线来分隔单词。这是一个例子:
let my_awesome_variable
两者都是可接受的命名约定,但您应该在代码中坚持其中一种以避免混淆。
常数变量
有时您需要在变量中存储永远不会改变的值。
常量变量是在程序运行期间其值不会改变的变量。在其他编程语言中,更改常量的值会产生错误。
在 JavaScript 中,常量变量是使用const关键字声明的。
下面展示了如何在 JavaScript 中声明 2 个常量:
const FILE_SIZE_LIMIT = 2000
const MAX_SPEED = 300
常量的命名约定是全部使用大写字母,但也可以使用小写字母。大写只是一个标准,让常量更加突出。
var 关键字
该var关键字用于声明具有全局作用域的变量。在 JavaScript 于 2015 年发布 newlet和const关键字之前,该关键字是唯一可以用来声明变量的关键字。
从今天开始,您应该var尽可能避免使用,因为var可能会引入错误,而您可以通过使用该let关键字来避免。
为了向您展示我的意思,请考虑以下示例:
if(true) {
var name = "Nathan";
}
console.log(name)
上面的代码可以name很好地打印变量,但实际上不应该,因为变量name是在if块内声明的。
这是因为使用var关键字声明的任何变量都可以从任何地方访问。该变量的范围是全局的。
另一方面,let关键字具有块作用域,这意味着该变量只能从该块及其所有子块访问。
但为什么要费心确定变量的范围呢?这是因为,当您有数百或数千行代码时,跟踪由于全局变量而发生的错误可能会变得令人沮丧。
软件开发中有一个原则称为“最少暴露原则”,这意味着您不会暴露程序中不必要的任何部分。
对变量进行块作用域可确保变量仅在需要该变量的代码库部分中公开和访问。
使用关键字声明的变量let与使用关键字声明的变量相同,var但范围级别除外。
if(true) {
let name = "Nathan";
}
console.log(name) // Error: name is not defined
这也意味着您现在可以使用var、let和const关键字来声明变量。使用哪一个?
一般来说,你可以用constfirst声明一个变量。当您编写应用程序并意识到需要更改变量分配时,可以将声明更改为let.
如果你从一开始就知道变量的值会改变,那么你可以let立即使用。只是今天不要使用var,否则人们可能会生你的气。
练习#2
编写一个包含三个变量的程序,每个变量具有以下值:
第一个变量包含您的名字
第二个变量包含您的年龄
第三个变量包含您的职业
然后使用该方法打印变量console.log()。这是示例输出:
John Doe
Student
19
概括
如何使用变量来编写一个程序来完成您想要它做的事情是作为程序员可以拥有的最重要的技能之一。
但在详细了解如何使用变量之前,让我们先了解一下 JavaScript 中的数据类型。
7 - JavaScript 基本数据类型
数据类型只是编程语言已知的不同数据类型的定义。
数据类型包含有关可以使用该数据执行哪些操作和不能执行哪些操作的规范。
向您展示一个对大脑友好的例子,我相信您同意这一点2 + 2 = 4?
嗯,JavaScript 也同意这一点:
console.log(2 + 2);
// Output: 4
但是,如果您尝试添加带有字母的数字(如下所示)怎么办?
console.log(2 + "ABC");
输出:
2ABC
将数字和字母添加在一起将导致 JavaScript 将这些值连接或连接在一起。
在本节中,您将学习 JavaScript 知道的基本数据类型:
弦乐
数字
布尔值
无效的
不明确的
您还将看到这些不同类型如何对运算符做出反应,+如上例所示。
首先,我们从字符串开始。
JavaScript 中的字符串
字符串只是定义为一系列字符的数据。
console.log()您之前在调用函数打印消息时已经看到过字符串数据的示例:
let message = "Hello, Sunshine!";
console.log(message); // Hello, Sunshine!
字符串需要用引号引起来。您可以使用双引号或单引号,但它们必须匹配。
当您使用不同的引号时,会出现错误,如下所示:
// Invalid or unexpected token
let message = "Hello';
您可以使用加号将两个或多个字符串连接为一个+。不要忘记在下一个字符串之前添加空格,否则您将得到一个没有空格的字符串!
let message = "Hello " + "and " + "Goodbye!";
console.log(message);
// Output: Hello and Goodbye!
打印变量值时,还可以console.log()直接在函数中添加字符串,如下所示:
let message = "Hello, Dave!";
console.log("The message is: " + message);
// Output: The message is: Hello, Dave!
当您在一个句子中有多个字符串到 console.log 时,这一点特别有用,如下所示:
let name = "John";
let topic = "JavaScript";
console.log(name + " is learning " + topic + " today");
// Output: John is learning JavaScript today
或者您也可以使用模板字符串格式,它允许您直接在字符串中嵌入变量,如下所示:
let name = "John";
let topic = "JavaScript";
console.log(`${name} is learning ${topic} today`);
// Output: John is learning JavaScript today
要使用模板字符串格式,您需要使用反引号()`字符而不是引号来包裹字符串。
使用美元符号和大括号将变量嵌入到字符串中,如 中所示${variable}。
这样,JavaScript 就知道您正在引用字符串内的变量。
当您要在一行中打印多个字符串时,模板字符串格式会更方便,因为您不必使用引号和连接来断开字符串。
接下来,字符串也可以表示数字。您可以将数字括在引号中,如下所示:
let score = "10" + "30";
console.log(score);
// Output: 1030
当您用符号连接两个字符串数字时+,JavaScript 将连接这两个数字而不是执行算术加法。
这就是字符串在 JavaScript 中的工作原理。接下来我们看一下数字。
JavaScript 中的数字(整数和浮点数)
数字数据类型代表不同类型的数字。JavaScript 中有两种类型的数字:
整数
花车
整数是没有小数和分数的整数。下面,您将看到两个整数x和的示例y:
let x = 1;
let y = 2;
console.log(x + y);
// Output: 3
另一方面,浮点数是指带有小数点的数字,如下所示:
let f = 1.2;
let z = 2.35;
console.log(f + z);
// Output: 3.55
要创建浮点数,您需要编写一个数字并用于.定义小数值。
使用数字类型,您可以执行算术运算,例如加法+、减法-、除法/和乘法,*就像使用计算器一样。
JavaScript 中的布尔值
trueBoolean 是一种表示和值的类型false。
您可以将布尔值视为只能处于两个位置之一的电灯开关:开或关。
编程语言中的布尔值也是如此。当 JavaScript 需要做出决定时使用它们:向左还是向右?对还是错?
以下是在 JavaScript 中创建布尔值的方法:
let on = true;
let off = false;
当您需要使用控制流做出决策时,经常使用此数据类型。您将在第 9 节中看到为什么布尔值在开发程序时非常有用。
JavaScript 中未定义
未定义是 JavaScript 中的一种数据类型,用于表示尚未分配任何值的变量。
每当您声明变量而不分配任何值时,该undefined值都会分配给该变量。例如:
let first_name;
console.log(first_name); // undefined
您还可以undefined显式分配给变量,如下所示:
let last_name = undefined;
但通常不建议这样做,因为 JavaScript 有另一个值叫做null,用于将变量标记为空。
JavaScript 中的空值
该null值是一种特殊的数据类型,表示空值或未知值。以下是将变量指定为 null 的方法:
let first_name = null;
上面的代码意味着 的值为first_name空或未知。
此时,您可能会想undefined和 之间有什么区别null?他们似乎有类似的目的。
你是对的。和undefined都是null不代表任何内容的值,而其他编程语言通常只有一个,那就是null。
在 JavaScript 中,undefined当声明变量时,该值被保留为默认值,而null意味着您故意为该变量分配一个“空”值。
当您稍后了解第 11 节中的函数时,这种细微的差异将会发挥作用。
现在,请记住 JavaScript 将其视为undefined“默认”空值和null“有意”空值。
8 - 类型转换和强制
有时,您可能希望将一种数据类型转换为另一种数据类型,以便程序按预期运行。
例如,假设您需要将字符串转换为整数,以便可以在数字之间执行加法。
如果您将其中一个数字作为字符串,JavaScript 会将它们连接在一起而不是相加:
let x = "7";
let y = 5;
console.log(x + y); // 75
要正确添加两个数字,您需要将x变量转换为整数。
将数据从一种类型更改为另一种类型也称为类型转换或类型转换。有 3 个函数经常用于进行类型转换:
Number()
String()
Boolean()
顾名思义,这些类型转换函数将尝试将您在括号内指定的任何值转换为同名类型。
要将字符串转换为整数,可以使用以下int()函数:
let x = "7";
let y = 5;
// Convert x to integer
x = Number(x);
console.log(x + y); // 12
另一方面,该String()函数将另一种类型的值转换为字符串。如果你输入String(true),那么你会得到“true”。
传递与函数相同类型的值没有任何效果。它只会返回相同的值。
类型强制
在 JavaScript 中,类型强制是一种将一种类型的值隐式转换为另一种类型的过程。
这是由 JavaScript 自动完成的,因此您的代码不会导致错误。但正如您将在本节中看到的,类型强制实际上可能会导致程序出现不良行为。
让我们考虑一下在 JavaScript 中执行 anumber和 a之间的加法时会发生什么:string
console.log(1 + "1");
正如您在上一节中所见,JavaScript 会将数字视为字符串并将两个字母连接为 as 而11不是将它们相加 ( 1 + 1 = 2)
但您需要知道其他编程语言不会以相同的方式响应。
Ruby 或 Python 等编程语言将通过停止程序并给出错误作为反馈来做出响应。它将响应类似“无法在数字和字符串之间执行加法”的内容。
但 JavaScript 会看到这一点并说:“我无法按原样执行您请求的操作,但如果将数字1转换为 a我可以执行此操作string,所以我会这样做。”
这正是类型强制。JavaScript 注意到它不知道如何执行您的代码,但它不会停止程序并返回错误。
相反,它会在不通知您的情况下更改其中一个值的数据类型。
虽然类型强制不会导致任何错误,但输出实际上也是您不想要的。
类型强制规则
类型强制规则从来没有在任何地方明确说明过,但我自己通过尝试各种愚蠢的代码确实找到了一些规则。
看来JavaScriptstring在发现不同的数据类型时会首先将数据类型转换为:
1 + "1" // "11"
[1 ,2] + "1" // "1,21"
true + "1" // "true1"
但是当你有一个对象时,值的顺序很重要。首先写入对象总是返回 numeric 1:
{ a: 1 } + "1" // 1
"1" + { a: 1 } // "1[object Object]"
true + { a: 1 } // "true[object Object]"
{ a: 1 } + 1 // 1
JavaScript 可以在布尔类型和数值类型之间进行计算,因为布尔值true和隐式具有和false的数值:1``0
true + 1 // 1+1 = 1
false + 1 // 0+1 = 1
[1,2] + 1 // "1,21"
类型强制总是隐式执行的。当您将值分配为变量时,变量类型在操作之外永远不会改变:
let myNumber = 1;
console.log(myNumber + "1"); // prints 11
console.log(myNumber); // still prints number 1 and not string
您可以尝试自己找到更多内容,但希望您现在已经了解强制转换是什么类型以及它是如何工作的。
为什么应该避免类型强制
在谈论类型强制时,JavaScript 开发人员通常分为两个阵营:
那些认为这是一个功能的人
那些认为这是一个错误的人
如果您问我,我建议您始终避免在代码中使用类型强制。
原因是我从未发现解决方案需要类型强制的问题,并且当我需要将一种类型转换为另一种类型时,最好明确地这样做:
let price = "50";
let tax = 5;
let totalPrice = Number(price) + Number(tax);
console.log(totalPrice);
使用显式类型转换函数(例如Number()和 )String()将使您的代码清晰透明。您无需猜测程序中所需的正确数据类型。
类型强制是 JavaScript 中可能会让初学者感到困惑的独特功能之一,因此最好尽早弄清楚。
接下来,我们将学习 JavaScript 运算符。
9 - JavaScript 中的运算符
顾名思义,运算符是可用于对数据执行操作的符号。
您已经看到了一些使用加号+运算符连接多个字符串并将两个数字相加的示例。当然,正如您将在本节中发现的那样,JavaScript 有多个运算符。
由于您之前已经了解了数据类型和转换,因此学习运算符应该相对容易。
算术运算符
算术运算符用于执行加法和减法等数学运算。
这些运算符经常与数字数据类型一起使用。这是一个例子:
console.log(10 - 3); // 7
console.log(2 + 4); // 6
JavaScript 中总共有 8 个算术运算符:
姓名操作示例意义添加x + y返回两个操作数之间的和减法x - y返回两个操作数之间的差乘法x * y返回两个操作数之间的乘法求幂x ** y返回左操作数的右操作数次方的值分配x / y返回左操作数除以右操作数的值余x % y返回左操作数除以右操作数后的余数增量x++返回操作数加一递减x--返回操作数减一
这些运算符非常简单,因此您可以自己尝试。
正如您在上一节中所看到的,该+运算符还可以用于字符串数据以将多个字符串合并为一个:
let message = "Hello " + "human!";
console.log(message); // Hello human!
当您添加数字和字符串时,JavaScript 将执行类型强制并将数字值视为字符串值:
let sum = "Hi " + 89;
console.log(sum); // Hi 89
对字符串使用任何其他算术运算符都会导致 JavaScript 返回一个NaN值。
赋值运算符
下一个要学习的运算符是赋值运算符,它由等号表示=。
在 JavaScript 中,赋值运算符用于将数据或值分配给变量。
您之前已经看过一些使用赋值运算符的示例,所以这里有一个提醒:
// Assign the string value 'Hello' to the 'message' variable
let message = "Hello";
// Assign the Boolean value true to the 'on' variable
let on = true;
您可能已经注意到,等号在编程中的含义与在数学中的含义略有不同,您是对的!
在编程中,赋值运算符不用于比较一个数字是否等于另一个数字。
如果你想进行这种比较,那么你需要使用等于==运算符。
赋值运算符还可以与算术运算符组合使用,以便您可以从左侧操作数中添加或减去值。
赋值运算符的类型见下表:
姓名操作示例意义任务x = yx = y加法作业x += yx = x + y减法作业x -= yx = x - y乘法作业x *= yx = x * y分区分配x /= yx = x / y余数分配x %= yx = x % y
接下来,我们来看看比较运算符。
比较运算符
比较运算符用于比较两个值。此类别中的运算符将返回布尔值:true或false。
下表显示了 JavaScript 中可用的所有比较运算符:
姓名操作示例意义平等的x == ytrue如果操作数相等则返回不等于x != ytrue如果操作数不相等则返回严格等于x === y返回true操作数是否相等且类型相同严格不等于x !== ytrue如果操作数不相等或具有不同类型则返回比...更棒x > ytrue如果左操作数大于右操作数则返回大于或等于x >= ytrue如果左操作数大于或等于右操作数则返回少于x < ytrue如果左操作数小于右操作数则返回小于或等于x <= ytrue如果左操作数小于或等于右操作数则返回
以下是使用这些运算符的一些示例:
console.log(9 == 9); // true
console.log(9 != 20); // true
console.log(2 > 10); // false
console.log(2 < 10); // true
console.log(5 >= 10); // false
console.log(10 <= 10); // true
比较运算符也可用于比较字符串,如下所示:
console.log("ABC" == "ABC"); // true
console.log("ABC" == "abc"); // false
console.log("Z" == "A"); // false
字符串比较区分大小写,如上面的示例所示。
JavaScript 每个比较运算符也有两个版本:宽松的和严格的。
在严格模式下,JavaScript 将比较类型而不执行类型强制。
您需要=在运算符中再添加一个等号,如下所示
console.log("9" == 9); // true
console.log("9" === 9); // false
console.log(true == 1); // true
console.log(true === 1); // false
您应该使用严格的比较运算符,除非您有特定的理由不这样做。
逻辑运算符
逻辑运算符用于检查一个或多个表达式的结果是否为True或False。
JavaScript 具有三个逻辑运算符:
姓名操作示例意义逻辑与x && ytrue如果所有操作数均为 则返回true,否则返回false逻辑或x || ytrue如果操作数之一为 则返回true,否则返回false逻辑非!x反转结果:返回trueif false,反之亦然
这些运算符只能返回布尔值。例如,您可以确定“7是否大于2”和“5是否大于4”:
console.log(7 > 2 && 5 > 4); // true
这些逻辑运算符遵循数理逻辑定律:
&&AND 运算符 - 如果有任何表达式返回false,则结果为false
||OR 运算符 - 如果有任何表达式返回true,则结果为true
!NOT 运算符 - 对表达式求反,返回相反值。
我们来做点运动吧。尝试在您的计算机上运行这些语句。你能猜出结果吗?
console.log(true && false);
console.log(false || false);
console.log(!true);
当您需要断言代码中满足特定要求时,这些逻辑运算符将派上用场。
typeof操作员
JavaScript 允许您使用运算符检查数据类型typeof。要使用该运算符,您需要在指定数据之前调用它:
let x = 5;
console.log(typeof x) // 'number'
console.log(typeof "Nathan") // 'string'
console.log(typeof true) // 'boolean'
该typeof运算符以字符串形式返回数据类型。“数字”类型代表整数和浮点类型,字符串和布尔值代表它们各自的类型。
练习#3
猜猜这些运算符的实际结果:
console.log(19 % 3);
console.log(10 == 3);
console.log(10 !== "10");
console.log(2 < "10");
console.log("5" > 2);
console.log((false && true) || false);
10 - JavaScript 数组
数组是一种对象数据类型,可用于保存多个值。数组可以是字符串、数字、布尔值、对象或它们的组合的列表。
要创建数组,您需要使用方括号[]并使用逗号分隔各个项目。
创建字符串列表的方法如下:
let birds = ['Owl', 'Eagle', 'Parrot', 'Falcon'];
您可以将数组视为项目列表,每个项目都存储在一个储物柜隔间中:
您还可以声明一个没有任何值的空数组:
let birds = [];
数组还可以包含如下值的混合:
let mixedArray = ['Bird', true, 10, 5.17]
上面的数组包含一个字符串、一个布尔值、一个整数和一个浮点数。
数组索引位置
JavaScript 会记住数组中元素的位置。元素的位置也称为索引号。
回到储物柜的例子,您可以将索引号视为储物柜号。索引号从0以下开始:
[x]要访问或更改数组的值,您需要在数组名称旁边添加方括号符号,其中x是该元素的索引号。这是一个例子:
// Access the first element in the array
myArray[0];
// Access the second element in the array
myArray[1];
假设您想从数组中打印字符串“Owl” birds。以下是您可以如何做到这一点。
let birds = ['Owl', 'Eagle', 'Parrot', 'Falcon'];
console.log(birds[0]); // Owl
console.log(birds[1]); // Eagle
就这样吧。您需要键入数组的名称,然后键入用方括号括起来的索引号。
您还可以使用赋值运算符将新值分配给特定索引。
让我们将“Parrot”替换为“Vulture”:
let birds = ['Owl', 'Eagle', 'Parrot', 'Falcon'];
birds[2] = 'Vulture';
console.log(birds);
// ['Owl', 'Eagle', 'Vulture', 'Falcon']
由于数组索引从零开始,因此值“Parrot”存储在索引 2 而不是 3 处。
数组操作的特殊方法
由于数组是一个对象,因此您可以调用 JavaScript 提供的方法来操作数组值。
例如,您可以使用该push()方法将一个项目添加到数组的末尾:
let birds = ['Owl', 'Eagle'];
birds.push('Sparrow');
console.log(birds);
// ['Owl', 'Eagle', 'Sparrow']
调用的另一个方法pop()可用于从数组末尾删除项目:
let birds = ['Owl', 'Eagle', 'Sparrow'];
birds.pop();
console.log(birds);
// ['Owl', 'Eagle']
该unshift()方法可用于从索引 0 处的前面添加一个项目:
let fishes = ['Salmon', 'Goldfish', 'Tuna'];
fishes.unshift('Sardine');
console.log(fishes);
// ['Sardine', 'Salmon', 'Goldfish', 'Tuna']
另一方面,该shift()方法可用于从索引 0 中删除项目:
let fishes = ['Salmon', 'Goldfish', 'Tuna'];
fishes.shift();
console.log(fishes);
// ['Goldfish', 'Tuna']
该indexOf()方法可用于查找并返回数组中项目的索引。
-1当在数组中找不到该项目时,该方法将返回:
let fishes = ['Salmon', 'Goldfish', 'Tuna'];
let pos = fishes.indexOf('Tuna');
console.log(pos); // 2
要获取数组的大小,您可以访问该length属性:
let fishes = ['Salmon', 'Goldfish', 'Tuna'];
console.log(fishes.length); // 3
请注意,我们不会在length上面的关键字旁边添加括号。这是因为length是数组对象的属性而不是方法。
我们将在接下来的教程中了解有关对象的更多信息。
练习#4
创建一个名为colors包含“红色”、“绿色”和“蓝色”颜色的数组。
首先,在数组的最后一个索引后添加“黑色”颜色。然后打印数组。
接下来,删除值“红色”并交换“绿色”和“蓝色”的位置。打印数组。
最后,在数组的第一个索引上添加颜色“黄色”,然后打印数组。
结果输出如下:
[ 'red', 'green', 'blue', 'black' ]
[ 'blue', 'green', 'black' ]
[ 'yellow', 'blue', 'green', 'black' ]
您需要使用本节中介绍的方法修改原始数组。
11 - JavaScript 中的控制流(条件)
到目前为止,您编写的 JavaScript 代码都是从上到下逐行执行的。但是,如果您只想在满足特定条件时运行某些代码行怎么办?
计算机程序通常需要考虑程序执行期间可能出现的许多不同条件。
这类似于人类在生活中做出决定的方式。例如,您有钱去日本度假吗?如果是的话,就去吧。如果没有,那就多存点钱吧!
这就是控制流的用武之地。控制流是编程语言中的一项功能,允许您根据可能出现的不同条件有选择地运行特定代码。
使用控制流允许您根据程序中存在的条件定义程序可以采用的多个路径。
JavaScript 中常用的控制流有两种类型:条件和循环。
本节将重点介绍条件语句,例如:
if...else陈述
switch...case陈述
您将在下一节中了解循环语句。
if...else 语句
该if语句允许您创建一个仅在满足特定条件时运行的程序。
该if语句的语法如下:
if (condition) {
// code to execute if condition is true
}
让我们看一个例子。假设你想去度假,需要 5000 美元。
使用该if语句,您可以通过以下方式检查您是否有足够的余额:
let balance = 7000;
if (balance > 5000) {
console.log("You have the money for this trip. Let's go!");
}
运行上面的代码一次,您将看到终端上打印的字符串。
balance现在更改to的值3000,您将不会得到任何响应。
发生这种情况是因为语句内的代码if仅在条件为 时才执行true。
在该if语句之后,您可以在其下面再编写一行代码,如下所示:
let balance = 7000;
if (balance > 5000) {
console.log("You have the money for this trip. Let's go!");
}
console.log("The end!");
console.log()无论您为变量分配什么值,上面的第二个调用都会执行balance。
如果您希望它仅在满足条件时执行if,则也将该行放在大括号内:
let balance = 7000;
if (balance > 5000) {
console.log("You have the money for this trip. Let's go!");
console.log("The end!");
}
接下来,假设您只需要在if不满足语句条件时运行一些代码。
这就是else语句的用武之地。语句仅在语句未满足else时才用于运行代码。if
这是一个例子:
let balance = 7000;
if (balance > 5000) {
console.log("You have the money for this trip. Let's go!");
} else {
console.log("Sorry, not enough money. Save more!");
}
console.log("The end!");
现在将 的值更改balance为小于5000,您将触发else示例中的块。
JavaScript 还具有else if语句,允许您编写另一个条件来检查if语句条件是否不满足。
考虑下面的例子:
let balance = 7000;
if (balance > 5000) {
console.log("You have the money for this trip. Let's go!");
} else if (balance > 3000) {
console.log("You only have enough money for a staycation");
} else {
console.log("Sorry, not enough money. Save more!");
}
console.log("The end!");
当balance金额小于时5000,else if报表将检查是否balance大于3000。如果是这样,程序将继续建议您在家度假。
您可以根据需要编写任意数量的else if语句,并且仅当前一条语句不满足时才会执行每一条语句。
这些语句一起if..else..else if允许您根据程序面临的条件执行不同的代码块。
switch...case 语句
该switch语句是核心 JavaScript 语法的一部分,可让您控制代码的执行流程。
它通常被认为是语句的替代方案if..else,可以为您提供更具可读性的代码,尤其是当您有许多不同的条件需要评估时。
这是工作声明的示例switch。我将解释下面的代码:
let age = 15;
switch (age) {
case 10:
console.log("Age is 10");
break;
case 20:
console.log("Age is 20");
break;
default:
console.log("Age is neither 10 or 20");
}
首先,您需要将要由语句计算的表达式传递switch到括号中。在示例中,age变量作为求值的参数传递。
然后,您需要编写语句将尝试与表达式匹配case的值。switch该case值后面紧跟一个冒号 ( :) 以标记 case 块的开始:
case "apple":
case`请记住要与表达式匹配的值的数据类型。如果你想匹配 a `string`,那么你需要放置 a `string`。当您有 a作为参数但为 case放置 a 时,`switch`语句**不会执行类型强制:**`number``string
switch (1) {
case "1":
console.log("Hello World!");
break;
}
数字表达式与字符串大小写值不匹配,因此 JavaScript 不会将任何内容记录到控制台。
布尔值也会发生同样的情况。该数字1不会被强制,因为true并且该数字0不会被强制为false:
switch (0) {
case true:
console.log("Hello True!");
break;
case false:
console.log("Bonjour False!");
break;
default:
console.log("No matching case");
}
switch 语句体
语句主体switch由三个关键字组成:
case用于启动 case 块的关键字
break用于停止switch语句运行下一个的关键字case
default未找到匹配时运行一段代码的关键字case。
当您的表达式找到匹配的 时case,JavaScript 将执行该case语句后面的代码,直到找到break关键字。如果省略关键字break,则代码将继续执行到下一个块。
看一下下面的例子:
switch (0) {
case 1:
console.log("Value is one");
case 0:
console.log("Value is zero");
default:
console.log("No matching case");
}
当您执行上面的代码时,JavaScript 将打印以下日志:
> "Value is zero"
> "No matching case"
这是因为如果没有break关键字,switch即使已经找到匹配的情况,也会继续根据剩余的情况评估表达式。
您的 switch 评估可能会匹配多个案例,因此break关键字通常用于在找到匹配项后退出流程。
最后,您还可以将表达式作为case值:
switch (20) {
case 10 + 10:
console.log("value is twenty");
break;
}
但您需要记住,case块的值必须与参数完全匹配switch。
使用该语句时最常见的错误之一switch是人们认为case价值被评估为true或false。
以下case块在语句中不起作用switch:
let age = 5;
switch (age) {
case age < 10:
console.log("Value is less than ten");
break;
case age < 20:
console.log("Value is less than twenty");
break;
default:
console.log("Value is twenty or more");
}
if您需要记住和评估之间的差异case:
if当测试条件评估为时,块将被执行true
case当测试条件与给定参数完全匹配时,块将被执行switch
Switch 语句用例
if当你考虑和之间的经验法则switch是:
switch`仅当代码编写起来很麻烦时才使用`if
例如,假设您想根据工作日编号编写工作日名称
您可以这样写:
let weekdayNumber = 1;
if (weekdayNumber === 0) {
console.log("Sunday");
} else if (weekdayNumber === 1) {
console.log("Monday");
} else if (weekdayNumber === 2) {
console.log("Tuesday");
} else if (weekdayNumber === 3) {
console.log("Wednesday");
} else if (weekdayNumber === 4) {
console.log("Thursday");
} else if (weekdayNumber === 5) {
console.log("Friday");
} else if (weekdayNumber === 6) {
console.log("Saturday");
} else {
console.log("The weekday number is invalid");
}
我不了解你,但上面的代码对我来说确实看起来很麻烦!尽管上面的代码没有任何问题,但您可以使用以下命令使其更漂亮switch:
let weekdayNumber = 1;
switch (weekdayNumber) {
case 0:
console.log("Sunday");
break;
case 1:
console.log("Monday");
break;
case 2:
console.log("Tuesday");
break;
case 3:
console.log("Wednesday");
break;
case 4:
console.log("Thursday");
break;
case 5:
console.log("Friday");
break;
case 6:
console.log("Saturday");
break;
default:
console.log("The weekday number is invalid");
}
当您有很多条件要评估同一块时,您可能会if使用逻辑运算符AND ( &&)或OR( ||)组合多个条件:
let myFood = "Banana";
if (myFood === "Banana" || myFood === "Apple") {
console.log("Eat fruits everyday to keep you healthy.");
}
if (myFood === "Chocolate Cake") {
console.log("Enjoy the sweet treat.");
}
您可以使用 switch 语句替换上面的代码。关键是你需要将多个堆叠cases为一个,如下所示:
let myFood = "Banana";
switch (myFood) {
case "Banana":
case "Apple":
console.log("Eat fruits everyday to keep you healthy.");
break;
case "Chocolate Cake":
console.log("Enjoy the sweet treat.");
break;
}
不幸的是,由于评估的工作方式,switch无法替换if使用运算符的多个条件。您需要为此使用该声明。&&caseif
练习#5
小学根据学生的成绩给予不同的奖励:
获得 A 的学生将获得巧克力
获得 B 的学生将获得一块 Cookie
获得 C 的学生将获得糖果
对于任何其他值,请打印“无奖励”。
创建一个名为 的变量grade来存储学生的成绩。
输出示例:
You got an A, so here's a Chocolate for you!
You got a B, here's a Cookie for you!
You got a C, there's room for improvement and here's your Candy!
您可以使用 theif...else或该switch...case语句。
12 - JavaScript 中的控制流(循环)
当您使用 JavaScript 编写应用程序时,您通常需要编写一段需要重复执行的代码。
假设您要编写一个在控制台中打印数字 1 到 10 的程序。console.log您可以通过像这样调用 10 次来完成:
console.log(1);
console.log(2);
console.log(3);
console.log(4);
console.log(5);
// and so on..
这是可行的,但是有更好的方法来编写这种重复性任务。
循环语句是另一类控制流语句,用于多次执行代码块直到满足特定条件。
JavaScript 中有两种循环语句:
声明for_
声明while_
让我们学习如何在实践中使用这些语句。
for 语句
您可以使用该for语句并只编写一行代码,而不是重复 10 次来打印数字 1 到 10,如下所示:
for (let x = 0; x < 10; x++) {
console.log(x);
}
就这样吧!该for语句后面是括号 ( ()),其中包含 3 个表达式:
表达式initialization,在其中声明要用作循环条件源的变量。x = 1如示例中所示。
表达式condition,其中初始化中的变量将根据特定条件进行评估。x < 11如示例中所示。
表达式arithmetic,其中变量值在每个循环结束时递增或递减。
这些表达式由分号 ( ;)分隔
在表达式之后,大括号 ( {}) 将用于创建一个代码块,只要表达式condition返回,JavaScript 就会执行该代码块true。
您可以通过注意语句结尾的分号 ( ;) 来识别哪个表达式是哪个。
for ( [initialization]; [condition]; [arithmetic expression]) {
// As long as condition returns true,
// This block will be executed repeatedly
}
算术表达式可以是自增 ( ++) 或自减 ( --) 表达式。每次大括号内的代码执行结束时都会运行一次:
for (let x = 10; x >= 1; x--) {
console.log(x);
}
或者您也可以使用速记算术运算符,例如+=和 ,-=如下所示:
// for statement with shorthand arithmetic expression
for (let x = 1; x < 20; x += 3) {
console.log(x);
}
这里,每次执行循环时x都会增加3。
循环结束后,JavaScript 将继续执行您在正文下方编写的任何代码for:
for (let x = 1; x < 2; x++) {
console.log(x);
}
console.log("The for loop has ended");
console.log("Continue code execution");
何时使用 for 循环
当您知道需要执行重复任务多少次时, for 循环非常有用。
例如,假设您正在编写一个抛硬币的程序。您需要计算抛掷 10 次硬币时正面朝上的次数。您可以使用以下方法来完成Math.random:
当数字低于0.5您需要增加tails计数器时
当数字大于0.5或等于时,您必须递增heads计数器
let heads = 0;
let tails = 0;
for (x = 1; x <= 10; x++) {
if (Math.random() < 0.5) {
tails++;
} else {
heads++;
}
}
console.log("Tossed the coin ten times");
console.log(`Number of heads: ${heads}`);
console.log(`Number of tails: ${tails}`);
上面的示例显示了for循环在何处提供最有效的方法。
现在让我们看一个关于抛硬币的替代练习,其中for循环无效:
找出需要抛硬币多少次才能使其正面朝上。
这一次,你不知道需要抛硬币多少次。这是您需要使用while循环语句的地方,您接下来将要学习它。
while 语句
只要条件计算结果为 ,语句或循环就用于运行代码while块。while``true
您可以按如下方式定义循环的条件和语句:
while (condition) {
statement;
}
就像for循环一样,while循环用于一遍又一遍地执行一段代码,直到达到所需的条件。
在下面的示例中,下面将继续执行语句块,直到条件表达式返回false:
let i = 0;
while (i < 6) {
console.log(`The value of i = ${i}`);
i++;
}
这里,只要小于,while循环就会重复打印 的值。在每次迭代中, 的值都会增加 1,直到达到 6 并终止循环。ii6``i
请记住,您需要包含一段代码,最终将评估条件变为false,否则while循环将永远执行。下面的例子将导致无限循环:
let i = 0;
while (i < 6) {
console.log(`The value of i = ${i}`);
}
因为 的值i永远不会改变,所以 while 循环将永远持续下去!
何时使用 while 循环
既然whileand 都for可以用于重复执行一段代码,那么什么时候应该使用while循环而不是for?
知道何时应该使用的一个简单方法while是当您不知道需要执行代码多少次时。
回到抛硬币的例子,有一种情况非常适合循环while:
找出需要抛硬币多少次才能使其正面朝上。
您还需要显示抛硬币的次数,直到硬币正面朝上:
let flips = 0;
let isHeads = false;
while (!isHeads) {
flips++;
isHeads = Math.random() < 0.5;
}
console.log(`It took ${flips} flips to land on heads.`);
在这里,该条件isHead = Math.random() < 0.5模拟了抛掷一枚公平的硬币。当结果为 时true,表示硬币正面朝上,退出循环。
因为在得到数字 8 之前你无法知道需要循环多少次,所以需要使用循环while而不是循环for。
练习#6
编写一个程序,使用星号打印半金字塔,*如下所示:
*
**
***
****
*****
接下来,打印一个反向半金字塔,如下所示:
*****
****
***
**
*
13 - JavaScript 中的函数
函数只是为执行特定任务而编写的一段(或一块)代码。
例如,类型转换函数String()用于将另一种类型的数据转换为字符串。
我们在前面的章节中学到的各种数组方法console.log()也是函数。但因为这些函数是从对象调用的,所以它们被称为方法。
您将在第 11 章后面了解有关方法的更多信息。现在,只需知道函数和方法本质上是相同的,只不过方法是从对象调用的。
除了 JavaScript 提供的内置函数之外,您还可以创建自己的函数。
如何创建自己的函数
创建函数首先键入function关键字,后跟函数名称、一对圆括号,然后是一对大括号。
这是一个例子:
function greet() {
// function body here
console.log("Hello!");
}
要调用函数,您需要指定函数名称,后跟括号:
greet(); // Hello!
当您调用该函数时,将执行该函数内部的代码。
函数参数和参数
参数是用于接受调用函数时给出的输入的变量。
您可以在函数头中的括号内指定参数。
以下示例显示了一个具有一个名为 的参数的函数name:
function greet(name) {
// function body
}
如何name在函数内使用该参数取决于您。
您可以在函数内部使用参数,print()如下所示:
function greet(name) {
console.log(`Hello, ${name}!`);
console.log("Nice weather today, right?");
}
现在,每当您需要调用该greet()函数时,您都需要传递一个输入来填充name参数。
您传递来填充参数的输入称为参数,具体操作方法如下:
greet("Peter");
调用函数时括号内的“Peter”字符串greet()将作为name参数传递。
运行代码以接收此输出:
Hello, Peter!
Nice weather today, right?
定义函数时可以有多个参数,但需要用逗号分隔每个参数,如下所示:
function greet(name, weather) {
console.log(`Hello, ${name}!`);
console.log(`It's ${weather} today, right?`);
}
greet("Nathan", "rainy");
输出:
Hello, Nathan!
It's rainy today, right?
当在函数头中指定两个参数时,需要传递两个参数。如果您调用该函数而不传递参数,则该值将为undefined。
在下一节中,您将学习如何创建具有默认值的参数,这样您就可以调用函数而无需向其传递参数。
但现在,我希望您能看到使用参数的便利性。它们通过采用不同的输入值来覆盖函数可能具有的各种场景,从而使您的函数更具适应性和可重用性。
如示例所示,name和weather参数允许您在不同的天气下问候许多不同的人。
无论晴天、雨天还是阴天,当你想和另一个人打招呼时,只要改变name和参数即可。weather
默认参数
定义函数时,您可以为该函数中的任何参数设置默认值。
例如,name下面函数中的参数是默认参数:
function greet(name = "Nathan") {
console.log(`Hello, ${name}!`);
console.log("Nice weather today, right?");
}
undefined此处,当没有为参数传递值或传递参数时,将使用默认值“Nathan” name。
您可以通过调用不带参数的函数来测试这一点,greet()如下所示:
greet();
greet("Jack");
输出:
Hello, Nathan!
Nice weather today, right?
Hello, Jack!
Nice weather today, right?
您定义的任何函数都可以混合使用默认和非默认参数。
下面是一个函数的另一个示例,该函数具有一个名为 的默认参数name和一个名为 的非默认参数weather:
function greet(weather, name = "Nathan") {
console.log(`Hello, ${name}!`);
console.log(`It's ${weather} today, right?`);
}
greet("sunny");
输出:
Hello, Nathan!
It's sunny today, right?
请注意,weather参数被放置在参数的前面name。这是为了方便,您无需指定默认参数。
如果将非默认参数放在默认参数之后,则需要向该name参数传递一个值才能获取该weather参数。
考虑下面的例子:
function greet(name = "Nathan", weather) {
console.log(`Hello, ${name}!`);
console.log(`It's ${weather} today, right?`);
}
greet(undefined, "sunny");
要将实参传递给weather形参,我们需要首先undefined为name形参传递 或 任何值。
这就是为什么最好在默认参数前面指定非默认参数。
默认参数和 null
undefined回到第 2 节,回想一下我们简要探讨了“默认”空值和null“有意”空值之间的区别。
当您传递undefined给具有默认参数的函数时,将使用默认参数:
function greet(name = "John"){
console.log(name);
}
greet(undefined); // John
John正如您所看到的,当您传递undefined给函数时,JavaScript 会打印默认参数值。
但是当你传递null给函数时,默认参数将被忽略:
function greet(name = "John"){
console.log(name);
}
greet(null); // null
这是初学者学习 JavaScript 时常犯的错误之一。当您使用 value 时null,JavaScript 会认为您希望该值为空,因此它不会用默认参数替换该值。
当您使用 时undefined,JavaScript 会将其替换为默认参数。您在职业生涯中使用 JavaScript 代码时可能会遇到此问题,因此请记住这一点。
返回语句
函数还可以return在代码块内有一条语句。语句return用于将值返回给调用者。
例如,以下函数返回两个值的总和:
function sum(a, b) {
return a + b;
}
let result = sum(3, 2);
console.log(result); // 5
函数返回的值可以分配给变量以进行进一步操作。return您可以在函数内的任何位置添加该语句。
当 JavaScript 到达该return语句时,它会跳过函数块内编写的进一步代码,并返回到调用该函数的位置。
以下函数有两个返回语句:
function checkAge(age) {
if (age > 18) {
return "You may get a car license";
}
return "You may not get a car license yet";
}
console.log(checkAge(20));
console.log(checkAge(15));
输出:
You may get a car license
You may not get a car license yet
当我们checkAge()第一次调用该函数时,age参数的值大于18,因此JavaScript执行块return内的语句if。
第二次调用该函数时,if条件不满足,因此 JavaScript 改为执行块return下的语句if。
您还可以通过指定不带任何值的语句来停止函数执行并返回调用者return:
function greet() {
console.log("Hello!");
return;
console.log("Good bye!");
}
greet()
输出:
Hello!
这里,在调用return之间调用该语句console.log()。
JavaScript 执行第一个console.log()调用,然后跳过其余代码。'再见!' 不打印字符串。
变量范围
现在您正在学习函数,现在是讨论变量作用域的好时机。
函数内部声明的变量只能从该函数访问。这是因为该变量具有局部作用域。
另一方面,在任何块之外声明的变量由于其全局作用域而被称为全局变量。
这两个作用域很重要,因为当您尝试访问其作用域之外的局部变量时,您会收到错误。例如:
function greet() {
let myString = "Hello World!";
}
greet();
console.log(myString);
当您运行上面的代码时,JavaScript 会返回错误:
ReferenceError: myString is not defined
这是因为该myString变量是在greet()函数内部声明的,因此您无法在函数外部访问该变量。即使您在访问变量之前调用该函数也没关系。
同时,可以从任何地方访问全局变量,甚至可以在函数内部访问:
let myString = "Hello World!";
function greet() {
console.log(myString);
}
greet(); // Hello World!
在这里,该greet()函数能够访问myString在其外部声明的变量。
请记住,这仅适用于使用let和声明的变量const。
接下来,您还可以定义一个与全局变量同名的局部变量,而不覆盖它。
这是一个例子:
let myString = "Hello World!";
function greet() {
let myString = "Morning!";
console.log(myString);
}
greet(); // Morning!
console.log(myString); // Hello World!
当您调用该greet()函数时,调用的局部变量myString被分配了字符串“Morning!”。
在函数外部,也被调用的全局变量myString仍然存在,并且值没有改变。
JavaScript 将局部作用域变量视为不同的变量。当您在函数内声明相同的变量时,函数内的任何代码将始终引用局部变量。
在实践中,你很少需要在不同的作用域中声明相同的变量:
在函数外部声明的任何变量都不应在函数内部使用,除非将它们作为参数传递。
函数内部声明的变量不应该在该函数外部引用
当您编写 JavaScript 函数时请记住这一点。
其余参数
剩余参数是可以接受任意数量的数据作为其参数的参数。参数将存储为数组。
您可以通过在参数名称前添加三个点来在函数头中定义剩余参数...。
以下是创建具有可变长度参数的函数的示例:
function printArguments(...args){
console.log(args);
}
调用printArguments()上面的函数时,您可以指定任意数量的参数:
function printArguments(...args){
console.log(args);
}
printArguments("A", "B", "C");
// [ 'A', 'B', 'C' ]
printArguments(1, 2, 3, 4, 5);
// [ 1, 2, 3, 4, 5 ]
请记住,一个函数只能有一个剩余参数,并且剩余参数必须是函数中的最后一个参数。
当您的函数需要使用不定数量的参数时,您可以使用剩余参数。
箭头功能
JavaScript箭头函数语法允许您使用更短、更简洁的语法编写 JavaScript 函数。
当您需要在 JavaScript 中创建函数时,主要方法是使用关键字function后跟函数名称,如下所示:
function greetings(name) {
console.log(`Hello, ${name}!`);
}
greetings("John"); // Hello, John!
箭头函数语法允许您创建一个函数表达式,该表达式产生与上面的代码相同的结果。
这是greetings()使用箭头语法的函数:
const greetings = (name) => {
console.log(`Hello, ${name}!`);
};
greetings("John"); // Hello, John!
当您使用箭头函数语法创建函数时,需要将表达式分配给变量,以便函数具有名称。
基本上,箭头函数语法如下所示:
const fun = (param1, param2, ...) => {
// function body
}
在上面的代码中,
fun是保存函数的变量。fun()您可以稍后在代码中调用该函数。
(param1, param2, ...)是函数参数。您可以根据函数的需要定义任意数量的参数。
然后您将看到箭头=>指示函数的开始。
上面的代码等同于以下内容:
const fun = function(param1, param2, ...) {
// function body
}
箭头函数语法没有为 JavaScript 语言添加任何新功能。
相反,它改进了用 JavaScript 编写函数的方式。
起初,这可能看起来很奇怪,因为您已经习惯了这个function关键字。
但当您开始使用箭头语法时,您会发现它非常方便且更易于编写。
单行和多行箭头函数
箭头函数为您提供了一种编写单行函数的方法,其中箭头的左侧=>返回到右侧。
使用function关键字时,需要使用大括号{}和return关键字,如下所示:
function plusTwo(num) {
return num + 2;
}
使用箭头函数,您可以省略大括号和return关键字,创建一个单行函数,如下所示:
const plusTwo = (num) => num + 2;
如果没有大括号,JavaScript 将计算箭头语法右侧的表达式并将其返回给调用者。
箭头函数语法也适用于没有值的函数,return如下所示:
const greetings = () => console.log("Hello World!");
使用箭头函数语法时,仅当您具有多行函数体时才需要大括号:
const greetings = () => {
console.log("Hello World!");
console.log("How are you?");
};
不带圆括号的箭头函数
JavaScript 函数中使用圆括号()来指示函数可以接收的参数。
当您使用function关键字时,圆括号始终是必需的:
function plusThree(num) {
return num + 3;
}
另一方面,当函数只有一个参数时,箭头函数允许您省略圆括号:
以下代码示例是有效的箭头函数表达式:
const plusThree = num => num + 3;
如您所见,您可以删除圆括号和大括号以及关键字return。
但在以下两种情况下您仍然需要圆括号:
当函数没有参数时
当函数有多个参数时
当没有参数时,箭头前需要圆括号,如下所示:
const greetings = () => console.log("Hello World!");
当您有多个参数时,这同样适用。
下面的函数有两个参数:name和age。
const greetings = (name, age) => console.log("Hello World!");
当您有单个参数函数时,箭头语法使圆括号可选。
箭头函数没有参数绑定
当使用function关键字定义函数时,您可以使用关键字访问传递给函数的参数,arguments如下所示:
const printArgs = function () {
console.log(arguments);
};
printArgs(1, 2, 3);
// [Arguments] { '0': 1, '1': 2, '2': 3 }
上面代码中的关键字arguments指的是存储传递给函数的所有参数的对象。
相比之下,箭头函数没有该arguments对象,并且当您尝试访问它时会抛出错误:
const printArgs = () => console.log(arguments);
printArgs(1, 2, 3);
//Uncaught ReferenceError: arguments is not defined
您可以使用 JavaScript 扩展语法来模仿arguments绑定,如下所示:
const printArgs = (...arguments) => console.log(arguments);
printArgs(1, 2, 3);
// [1, 2, 3]
通过使用扩展语法,传递给箭头函数的参数将存储在数组中。
请注意,即使您只向函数传递一个参数,您也需要圆括号。
arguments您可以使用数组索引符号arguments[0]、arguments[1]等来访问给定值。
如何轻松地将普通函数转换为箭头函数
您可以按照以下三个简单步骤将普通函数转换为箭头函数:
将function关键字替换为变量关键字let或const
=在函数名称之后、圆括号之前添加符号
=>在圆括号后添加符号
下面的代码将帮助您直观地了解这些步骤:
function plusTwo(num) {
return num + 2;
}
// step 1: replace function with let / const
const plusTwo(num) {
return num + 2;
}
// step 2: add = after the function name
const plusTwo = (num) {
return num + 2;
}
// step 3: add => after the round brackets
const plusTwo = (num) => {
return num + 2;
}
上述三个步骤足以将任何旧的 JavaScript 函数语法转换为新的箭头函数语法。
当您有单行函数时,有第四个可选步骤来删除大括号和关键字,return如下所示:
// from this
const plusTwo = num => {
return num + 2;
};
// to this
const plusTwo = num => num + 2;
当只有一个参数时,还可以删除圆括号:
// from this
const plusTwo = (num) => num + 2;
// to this
const plusTwo = num => num + 2;
但最后两个步骤是可选的。只需前三个步骤即可转换任何 JavaScriptfunction并使用箭头函数语法。
练习#7
编写一个名为 的函数calculateSquare(),用于计算正方形的面积和周长。
该函数接受一个参数:side平方的 。
面积的计算公式为side * side,周长的计算公式为4 * side。
输出显示尺寸、面积和周长的大小,如下所示:
The square side is 8
The area of the square is 64
The perimeter of the square is 32
14 - JavaScript 中的对象
对象是一种特殊的数据类型,它允许您存储多个值,就像数组一样。
对象和数组之间的区别在于,数组将数据存储为项目列表,而对象以对格式存储数据key:value。
让我们看一个例子来说明这种差异。假设您想在程序中存储有关一本书的信息。
当您使用常规变量时,它看起来像这样:
let bookTitle = "JavaScript Introduction";
let bookAuthor = "Nathan Sebhastian";
虽然它工作得很好,但它肯定不是存储相关值的最佳方式。
存储值的另一种方法是使用数组:
let myBook = ["JavaScript Introduction", "Nathan Sebhastian"];
这当然更好,因为您可以将有关本书的相关数据分组在一起,但您无法为该值添加上下文。
这就是对象有用的地方。您可以声明一个书籍对象并以以下格式存储数据key:value:
let myBook = {
title: "JavaScript Introduction",
author: "Nathan Sebhastian",
};
对象是使用大括号声明的{},括号内的每一项都以格式编写key:value。
对象项也称为属性,键为属性名称,值为属性值。
与数组一样,您需要使用逗号分隔对象内的每个项目。
您可以指定字符串或数字作为项目的键,并且可以指定任何类型的数据作为值,包括函数:
let myBook = {
title: "JavaScript Introduction",
author: "Nathan Sebhastian",
describe: function () {
console.log(`Book title: ${this.title}`);
console.log(`Book author: ${this.author}`);
},
};
这里,键或属性是一个从对象describe打印title和值的函数。author
关键字this指的是代码的上下文,myBook在本例中是对象。
通常,对象键可以为它所保存的值提供更多上下文。键还必须是唯一的,因此不能在同一个对象中使用同一个键两次。
例如,如果您有关于一本书的数据,则可以使用对象键(例如title、author和 )price来帮助您了解每个键中存储的值的上下文。
如何访问对象值
要访问对象的值,可以使用点符号.或方括号[]符号。
下面是使用点表示法访问对象属性的示例:
let myBook = {
title: "JavaScript Introduction",
author: "Nathan Sebhastian",
};
console.log(myBook.title);
console.log(myBook.author);
以下是如何使用方括号访问相同的属性:
let myBook = {
title: "JavaScript Introduction",
author: "Nathan Sebhastian",
};
console.log(myBook["title"]);
console.log(myBook["author"]);
请记住,您需要将属性名称像字符串一样用引号括起来,否则 JavaScript 会认为您在方括号内传递了变量。
如何向对象添加新属性
您可以使用点符号或方括号为对象分配新属性,如下所示:
let myBook = {
title: "JavaScript Introduction",
author: "Nathan Sebhastian",
};
// add release year property
myBook.year = 2023;
// add publisher property
myBook["publisher"] = "CodeWithNathan";
console.log(myBook);
当您打印对象时,结果如下:
{
title: 'JavaScript Introduction',
author: 'Nathan Sebhastian',
year: 2023,
publisher: 'CodeWithNathan'
}
您可以根据需要向同一对象添加任意数量的属性。
如何修改对象属性
要修改现有属性,您需要使用点或方括号表示法后跟赋值运算符来指定现有对象属性,如下所示:
let myBook = {
title: "JavaScript Introduction",
author: "Nathan Sebhastian",
};
// change the author property
myBook.author = "John Doe";
console.log(myBook);
输出:
{
title: 'JavaScript Introduction',
author: 'John Doe'
}
如您所见,author属性值已更改。
如何删除对象属性
要从对象中删除属性,您需要使用delete运算符,如下所示:
let myBook = {
title: "JavaScript Introduction",
author: "Nathan Sebhastian",
};
delete myBook.author;
console.log(myBook);
输出:
{ title: 'JavaScript Introduction' }
当您尝试访问已删除的属性时,您将获得该undefined值。
如何检查对象中是否存在属性
要检查对象中是否存在某个属性,可以使用in如下运算符:
propertyName in myObject
如果对象中存在该运算符,则该in运算符将返回。true``propertyName
请参阅下面的示例:
let person = {
firstName: "Nathan",
lastName: "Sebhastian"
}
// check if firstName exists
console.log('firstName' in person); // true
// check if age exists
console.log('age' in person); // false
现在您知道如何操作 JavaScript 对象了。
练习#8
创建一个person具有以下属性的对象:
name- 此人的姓名
age- 该人的年龄
greet()- 问候他人的功能
在greet()函数内,介绍此人,指定姓名和年龄。
这是一个示例输出:
person.greet();
Hello! My name is Alex and I'm 22 years old.
最后练习:构建一台收银机
让我们构建一个收银机,它可以将商品添加到购物车、计算总价、计算折扣并接受现金付款。
假定货币为美元,因此您无需将其添加到程序中。
收银机有 3 种待售商品:
电话300
220 人智能电视
150 人游戏机
总价高于400有10%的折扣。
收银机应该有一个刚开始是空的购物车。
收银机应该提供一个名为 的方法addItem,该方法将商品名称作为参数。当接到电话时,它应该检查该商品是否可以出售。如果是,则应将该商品添加到购物车中。如果没有,请显示一条消息,说明我们不出售该商品。
收银机应该提供一个名为 的方法calculateTotalPrice来计算购物车中所有商品的总价。它应该迭代购物车中的商品并总结它们的价格。
收银机应该提供一个名为 的方法pay,以支付金额为参数。
它应该使用该方法计算购物车中商品的总价calculateTotalPrice。如果总价高于400,则应适用10%的折扣。
然后,该方法应将付款金额与总价(应用折扣后)进行比较,并显示相应的消息:
如果付款金额等于或大于总价,则应显示感谢客户购买的消息。如果有任何找零,还应显示要找的找零金额。
如果付款金额小于总价,则应显示一条消息,表明客户没有足够的钱来购买商品。
该程序应包括适当的console.log()语句来显示将商品添加到购物车、显示总价和处理付款的消息。
该程序应该处理客户的付款金额恰好等于总价的情况,以及付款金额大于或小于总价的情况。
要构建程序,您需要使用您所学到的有关对象、数组、条件和循环的知识。
我建议您首先尝试自己构建该程序。如果您遇到困难,请参阅下面提供的解决方案。祝你好运!
结论
恭喜您完成本手册!我们一起学习了很多概念来学习如何使用 JavaScript 进行编码。