JavaScript基础知识
# 2.1 运行脚本
# 2.1.1 script标签
我们几乎可以使用 <script>
标签将 JavaScript 程序插入到 HTML 文档的任何位置。
<script>
标签中包裹了 JavaScript 代码,当浏览器遇到 <script>
标签,代码会自动运行
# 2.1.2 script标签属性
<script>
标签有一些现在很少用到的特性(attribute),但是我们可以在老代码中找到它们
# type 特性:<script type=…>
在老的 HTML4 标准中,要求 script 标签有 type 特性。通常是 type="text/javascript"。
# language 特性:<script language=…>
这个特性是为了显示脚本使用的语言。这个特性现在已经没有任何意义,因为语言默认就是 JavaScript
# 脚本前后的注释
在非常古老的书籍和指南中,你可能会在 <script>
标签里面找到注释,就像这样:
<script type="text/javascript"><!--
...
//--></script>
2
3
这些注释是用于不支持 <script>
标签的古老的浏览器隐藏 JavaScript 代码的。由于最近 15 年内发布的浏览器都没有这样的问题
# 2.1.3 外部脚本
脚本文件可以通过 src 特性(attribute)添加到 HTML 文件中
<script src="/path/to/script.js"></script>
# src路径
/path
脚本文件从网站根目录开始的绝对路径./path
脚本文件对于当前页面的相对路径https://path
完整的 URL 地址
# 外部脚本加载
- 浏览器会下载外部脚本,并将它保存到浏览器缓存中
- 其他页面想要相同的脚本就会从缓存中获取,而不是下载它。所以文件实际上只会下载一次
- 可以节省流量,并使得页面(加载)更快
警告
如果设置了 src 特性,script 标签内容将会被忽略
# 2.1.4 总结
- 我们可以使用一个
<script>
标签将 JavaScript 代码添加到页面中。 - type 和 language 特性(attribute)不是必需的。
- 外部的脚本可以通过
<script src="path/to/script.js"></script>
的方式插入。
# 2.2 代码结构
# 2.2.1 语句
语句是执行行为(action)的语法结构和命令。
我们可以在代码中编写任意数量的语句。语句之间可以使用分号进行分割。
通常,每条语句独占一行,以提高代码的可读性
# 2.2.2 分号
当存在换行符(line break)时,在大多数情况下可以省略分号
# 自动分号插入
JavaScript 将换行符理解成“隐式”的分号 在大多数情况下,换行意味着一个分号。但是“大多数情况”并不意味着“总是”
alert(3 +
1
+ 2);
2
3
存在 JavaScript 无法确定是否真的需要自动插入分号的情况
alert("Hello")
[1, 2].forEach(alert);
// 会理解为
alert("Hello")[1, 2].forEach(alert);
2
3
4
# 2.2.3 注释
单行注释以两个正斜杠字符 //
开始
多行注释以一个正斜杠和星号开始 “/*”
并以一个星号和正斜杠结束 “*/”
提示
在大多数的编辑器中,一行代码可以使用 Ctrl+/ 快捷键进行单行注释,诸如 Ctrl+Shift+/ 的快捷键可以进行多行注释(选择代码,然后按下快捷键)
警告
不支持注释嵌套
# 2.3 现代模式
ES5 规范增加了新的语言特性并且修改了一些已经存在的特性。为了保证旧的功能能够使用,大部分的修改是默认不生效的。你需要一个特殊的指令 —— "use strict"
来明确地激活这些特性
"use strict"
或者 'use strict'
。当它处于脚本文件的顶部时,则整个脚本文件都将以“现代”模式进行工作
"use strict"
可以被放在函数体的开头。这样则可以只在该函数中启用严格模式
警告
请确保 "use strict"
出现在脚本的最顶部,否则严格模式可能无法启用
没有办法取消 use strict
# 2.4 变量
变量是数据的命名存储
# 2.4.1 变量使用
# 变量声明
声明或者定义一个名为massage的变量let massage
可以将变量定义和赋值合并成一行let message = 'Hello!'
也可以在一行中声明多个变量let user = 'John', age = 25, message = 'Hello';
多次声明
声明两次会触发 error
一个变量应该只被声明一次。
对同一个变量进行重复声明会触发 error
# 变量赋值
对massage变量赋值message = 'Hello'
# 变量访问
访问massage变量alert(massage)
# 2.4.2 变量命名
# 变量命名限制
- 变量名称必须仅包含字母、数字、符号
$
和_
- 首字符必须非数字
如果命名包括多个单词,通常采用驼峰式命名法(camelCase)
js中变量名区分大小写
保留字
js中存在保留字无法用作变量命名
警告
未采用use strict
时可以通过直接赋值的方式使程序自动声明变量
但严格模式下则会报错
# 2.4.3 常量
声明一个常数(不变)变量,通常使用 const
而非 let
使用 const
声明的变量称为“常量”。它们不能被修改,如果你尝试修改就会发现报错
# 大写形式的常数
一般代码执行前就知晓且不变的数据用大写形式的常量存储,在代码执行过程中得到的不变的数据用普通常量存储
# 2.4.4 总结
我们可以使用 var、let 或 const 声明变量来存储数据。
let
— 现代的变量声明方式。var
— 老旧的变量声明方式。一般情况下,我们不会再使用它。但是,我们会在 老旧的 "var" 章节介绍 var 和 let 的微妙差别,以防你需要它们。const
— 类似于 let,但是变量的值无法被修改。 变量应当以一种容易理解变量内部是什么的方式进行命名
# 2.5 数据类型
# 2.5.1 动态类型
JavaScript 中的值都具有特定的类型
在 JavaScript 中有 8 种基本的数据类型(译注:7 种原始类型和 1 种引用类型)
JavaScript是动态类型(dynamically typed)的编程语言,虽然编程语言中有不同的数据类型,但是你定义的变量并不会在定义后,被限制为某一数据类型
# 2.5.2 Number
number 类型代表整数和浮点数
数字可以有很多操作,比如,乘法 *
、除法 /
、加法 +
、减法 -
等等。
除了常规的数字,还包括所谓的“特殊数值(“special numeric values”)”也属于这种类型:Infinity
、-Infinity
和 NaN
# Infinity
Infinity 代表数学概念中的 无穷大 ∞。是一个比任何数字都大的特殊值
我们可以通过除以 0 来得到它
或者在代码中直接使用它
# NaN
NaN 代表一个计算错误。它是一个不正确的或者一个未定义的数学操作所得到的结果
NaN 是粘性的。任何对 NaN 的进一步数学运算都会返回 NaN
NaN数学运算的例外
NaN ** 0
结果为 1
提示
在 JavaScript 中做数学运算是安全的。我们可以做任何事:除以 0,将非数字字符串视为数字,等等。
脚本永远不会因为一个致命的错误(“死亡”)而停止。最坏的情况下,我们会得到 NaN 的结果。
# 2.5.3 BigInt
"number" 类型无法表示大于 (253-1)
(即 9007199254740991
),或小于 -(253-1)
的整数
BigInt
类型是最近被添加到 JavaScript 语言中的,用于表示任意长度的整数。
可以通过将 n
附加到整数字段的末尾来创建 BigInt
值
# 2.5.4 String
在 JavaScript 中,有三种包含字符串的方式。
- 双引号:
"Hello"
. - 单引号:
'Hello'
. - 反引号:
`Hello`
.
双引号和单引号都是“简单”引用,在 JavaScript 中两者几乎没有什么差别
# 反引号
反引号是 功能扩展 引号。它们允许我们通过将变量和表达式包装在 ${…}
中,来将它们嵌入到字符串中
let name = "John";
// 嵌入一个变量
alert( `Hello, *!*${name}*/!*!` ); // Hello, John!
// 嵌入一个表达式
alert( `the result is *!*${1 + 2}*/!*` ); // the result is 3
2
3
4
5
${…}
内的表达式会被计算,计算结果会成为字符串的一部分。可以在 ${…}
内放置任何东西:诸如名为 name
的变量,或者诸如 1 + 2
的算数表达式,或者其他一些更复杂的
注意
需要注意的是,这仅仅在反引号内有效,其他引号不允许这种嵌入
# 2.5.5 Boolean
boolean 类型仅包含两个值:true
和 false
布尔值也可作为比较的结果
# 2.5.6 null值
特殊的 null
值不属于上述任何一种类型。
它构成了一个独立的类型,只包含 null
值
相比较于其他编程语言,JavaScript 中的 null
不是一个“对不存在的 object
的引用”或者 “null 指针”。
JavaScript 中的 null
仅仅是一个代表“无”、“空”或“值未知”的特殊值
# 2.5.7 undefined值
特殊值 undefined
和 null
一样自成类型
undefined
的含义是 未被赋值
如果一个变量已被声明,但未被赋值,那么它的值就是 undefined
注意
从技术上讲,可以显式地将 undefined
赋值给变量
但是不建议这样做。通常,使用 null
将一个“空”或者“未知”的值写入变量中,而 undefined
则保留作为未进行初始化的事物的默认初始值
# 2.5.8 Object
object
类型是一个特殊的类型,其他所有的数据类型都被称为“原始类型”,因为它们的值只包含一个单独的内容(字符串、数字或者其他)。相反,object
则用于储存数据集合和更复杂的实体
# 2.5.9 Symbol
symbol
类型用于创建对象的唯一标识符
# 2.5.10 typeof 运算符
typeof
运算符返回参数的类型
typeof undefined // "undefined"
typeof 0 // "number"
typeof 10n // "bigint"
typeof true // "boolean"
typeof "foo" // "string"
typeof Symbol("id") // "symbol"
typeof Math // "object" (1)
typeof null // "object" (2)
typeof alert // "function" (3)
2
3
4
5
6
7
8
9
typeof null
typeof null
的结果为 "object"
。这是官方承认的 typeof
的错误,这个问题来自于 JavaScript 语言的早期阶段,并为了兼容性而保留了下来。null
绝对不是一个 object
。null
有自己的类型,它是一个特殊值。typeof
的行为在这里是错误的。
function
typeof alert
的结果是 "function"
,因为 alert
在 JavaScript 语言中是一个函数。我们会在下一章学习函数,那时我们会了解到,在 JavaScript 语言中没有一个特别的 "function" 类型。函数隶属于 object
类型。但是 typeof
会对函数区分对待,并返回 "function"
。这也是来自于 JavaScript 语言早期的问题。从技术上讲,这种行为是不正确的,但在实际编程中却非常方便
`typeof(x)` 语法
你可能还会遇到另一种语法:typeof(x)
。它与 typeof x
相同。
简单点说:typeof
是一个操作符,不是一个函数。这里的括号不是 typeof
的一部分。它是数学运算分组的括号。
通常,这样的括号里包含的是一个数学表达式,例如 (2 + 2)
,但这里它只包含一个参数 (x)
。从语法上讲,它们允许在 typeof
运算符和其参数之间不打空格,有些人喜欢这样的风格。
有些人更喜欢用 typeof(x)
,尽管 typeof x
语法更为常见
# 2.5.11 总结
JavaScript 中有八种基本的数据类型(译注:前七种为基本数据类型,也称为原始类型,而 object
为复杂数据类型)。
number
用于任何类型的数字:整数或浮点数,在±(253-1)
范围内的整数。bigint
用于任意长度的整数。string
用于字符串:一个字符串可以包含 0 个或多个字符,所以没有单独的单字符类型。boolean
用于true
和false
。null
用于未知的值 —— 只有一个null
值的独立类型。undefined
用于未定义的值 —— 只有一个undefined
值的独立类型。symbol
用于唯一的标识符。object
用于更复杂的数据结构。
我们可以通过 typeof
运算符查看存储在变量中的数据类型。
- 通常用作
typeof x
,但typeof(x)
也可行。 - 以字符串的形式返回类型名称,例如
"string"
。 typeof null
会返回"object"
—— 这是 JavaScript 编程语言的一个错误,实际上它并不是一个object
# 2.6 交互
# 2.6.1 alert
浏览器中显示一条信息,并等待用户按下”OK”
弹出的这个带有信息的小窗口被称为 模态窗。"modal" 意味着用户不能与页面的其他部分(例如点击其他按钮等)进行交互,直到他们处理完窗口。在上面示例这种情况下 —— 直到用户点击“确定”按钮。
# 2.6.2 prompt
prompt
函数接收两个参数:
result = prompt(title, [default]);
浏览器会显示一个带有文本消息的模态窗口,还有 input 框和确定/取消按钮。
访问者可以在提示输入栏中输入一些内容,然后按“确定”键。然后我们在 result
中获取该文本。或者他们可以按取消键或按 key:Esc
键取消输入,然后我们得到 null
作为 result
。
prompt
将返回用户在 input
框内输入的文本,如果用户取消了输入,则返回 null
# title
显示给用户的文本
# default
可选的第二个参数,指定 input 框的初始值
# 2.6.2 confirm
result = confirm(question);
confirm
函数显示一个带有 question
以及确定和取消两个按钮的模态窗口。
点击确定返回 true
,点击取消返回 false
# 2.6.3 总结
我们学习了与用户交互的 3 个浏览器的特定函数:
alert
: 显示信息。
prompt
: 显示信息要求用户输入文本。点击确定返回文本,点击取消或按下 key:Esc
键返回 null
。
confirm
: 显示信息等待用户点击确定或取消。点击确定返回 true
,点击取消或按下 key:Esc
键返回 false
。
这些方法都是模态的:它们暂停脚本的执行,并且不允许用户与该页面的其余部分进行交互,直到窗口被解除。
上述所有方法共有两个限制:
- 模态窗口的确切位置由浏览器决定。通常在页面中心。
- 窗口的确切外观也取决于浏览器。我们不能修改它。