JavaScript 基础知识

Hello, world!

script 标签

JavaScript程序可以在 <script>标签的帮助下插入到 HTML 文档的任何地方。 比如:

js 复制代码
<!DOCTYPE HTML>
<html>
<body>
  <p>script 标签之前 ...</p>
  <script>
    alert('Hello, world!');
   </script>
<p>...script 标签之后</p>
</html>

外部脚本

如果你有大量的 JavaScript 代码,我们可以将它放入一个单独的文件

  • 通过src 特性(attribute)添加到 HTML 文件中。eg:
    <script src="/path/to/script.js"></script> /path/to/script .js 是脚本文件从网站根目录开始的绝对路径
  • 提供当前页面的相对路径。eg:
    src ="script .js" 表示当前文件夹中的 "script .js" 文件。
  • 提供一个完整的 URL 地址,eg:
    <script src="<https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js>"></script>

要附加多个脚本,则使用多个标签:

js 复制代码
<script src="/js/script1.js"></script>
<script src="/js/script2.js"></script>

一个单独的<script>标签不能同时有 src 特性和内部包裹的代码, 这将不会工作:

js 复制代码
<script src="file.js">
alert(1); // 此内容会被忽略,因为设定了 src
</script>

一般来说,只有最简单的脚本才嵌入到 HTML 中。更复杂的脚本存放在单独的文件中。这可以节省流量,并使得页面加载更快

代码结构

语句

语句是执行行为(action)的语法结构和命令

代码语句之间可以使用分号进行分割

例如,我们将 " Hello World" 这条信息一分为二:

js 复制代码
alert('Hello');
alert('World');

通常,每条语句独占一行,以提高代码的可读性

分号

大部分时候可以省略分号,但是最好不要省略分号

注释

添加注释描述代码做了什么和为什么要这样做

单行注释以两个正斜杠字符 // 开始

js 复制代码
//这行注释独占一行
alert('Hello');
alert('World'); // 这行注释跟随在语句后面

多行注释以一个正斜杠和星号开始 /*并以一个星号和正斜杆结束 */

js 复制代码
/* 两个消息的例子。
这是一个多行注释。
*/
alert('Hello');
alert('World');

快捷方式

在大多数的编辑器中,可以使用 Ctrl+/ 进行单行注释,Ctrl+Shift+/ 进行多行注释(选择代码,然后按下组合键)
不支持注释嵌套!

现代模式,"use strict"

"use strict"

"use strict"处于脚本文件的顶部时,则整个脚本文件都将以"现代"模式进行工作

  • "use strict"可以被放在函数体的开头。这样则可以只在该函数中启用严格模式。但通常人们会在整个脚本中启用严格模式
  • 只有注释可以出现在"use strict"的上面
  • use strict 一旦设置无法取消

浏览器控制台

当使用开发者控制台运行代码时,是默认不启动 use strict 的

有时,当 use strict 会对代码产生一些影响时,运行后会得到错误的结果。

在控制台中启用 use strict:

首先,可以尝试搭配使用 Shift+Enter 按键去输入多行代码,然后将 use strict 放在代码最顶部,就像这样:

js 复制代码
'use strict'; <Shift+Enter 换行>
// ...你的代码
<按下 Enter 以运行>

其在大部分浏览器中都有效,像 Firefox 和 Chrome

如果依然不行,例如你使用的是旧版本的浏览器,那么有一种很丑但可靠的启用 use strict 的方法------将你的代码放在这样的包装器中:

js 复制代码
(function() {
 'use strict';
// ...你的代码...
})()
  • 现代 JavaScript 支持 "classes" 和 "modules" ------ 高级语言结构(本教程后续章节会讲到),它们会自动启用 use strict 。因此,如果我们使用它们,则无需添加 "use strict" 指令

  • 目前最好还是将 "use strict"; 写在脚本的顶部。稍后,当代码全都写在了 class和 module 中时,则可以将 "use strict"; 这行代码省略掉

变量

JavaScript 应用需要处理信息。eg:

1.一个网上商店 ------ 这里的信息可能包含正在售卖的商品和购物车

2.一个聊天应用 ------ 这里的信息可能包括用户和消息等等

变量就是用来储存 这些信息的 变量是数据的"命名存储"。我们可以使用变量来保存商品、访客和其他信息

变量

在 JavaScript 中声明一个变量,需要用 let 关键字

js 复制代码
let message;//定义(声明)了一个名称为 "message" 的变量
message = 'Hello!';//通过赋值运算符 "=" 为变量添加一些数据
alert(message); // 显示变量内容Hello!

现在这个字符串已经保存到与该变量相关联的内存区域了,我们可以通过使用该变量名称访问它

简洁地,可以将变量定义和赋值合并成一行

js 复制代码
let message = 'Hello!'; // 定义变量,并且赋值
alert(message); // 显示变量内容Hello!

在一行中声明多个变量:

js 复制代码
let user = 'John', age = 25, message = 'Hello';

但并不推荐这样,为了更好的可读性,最好一行只声明一个变量

js 复制代码
let user = 'John';
let age = 25;
let message = 'Hello';

一些程序员采用下面的形式书写多个变量:

js 复制代码
let user = 'John',
    age = 25,
    message = 'Hello';

变量声明

变量的声明可以任意改变,声明值改变后,之前的数据就被从变量中删除了

js 复制代码
let message;
message = 'Hello!';
message = 'World!'; // 值改变了
alert(message);

还可以声明两个变量,然后将其中一个变量的数据拷贝到另一个变量

js 复制代码
let hello = 'Hello world!';
let message;
message = hello;// 将字符串 'Hello world' 从变量 hello 拷贝到 message
alert(hello); // Hello world!
alert(message); // Hello world!
// 现在两个变量保存着相同的数据

一个变量只能声明一次,对同一个变量进行重复声明会触发 error

  • 存在禁止更改变量值的函数式编程语言。比如 Scala 或 Erlang
    如果你试图保存其他值,它会强制创建一个新盒子(声明一个新变量),无法重用之前的变量

变量命名

JavaScript 的变量命名的要求:

  1. 变量名称必须仅包含字母,数字,符号 $ 和 _
  2. 首字符必须非数字
  3. 区分大小写
  • 如果命名包括多个单词,通常采用驼峰式命名法。即除了第一个单词,其他的每个单词都以大写字母开头:myVeryLongName
  • 保留字不能用作变量命名,如let 、 class 、 return 、 function

常量

声明一个常数(不变)变量,使用 const 声明的变量称为"常量"。它们不能被重新赋值,如果尝试修改就会发生报错

js 复制代码
const myBirthday = '18.04.1982';
myBirthday = '01.01.2001'; // 错误,不能对常量重新赋值

常量的用法

  1. 当程序员能确定这个变量永远不会改变的时候,就可以使用 const 来确保这种行为,并且清楚地向别人传递这一事实

  2. 将常量用作别名,以便记住那些在执行之前就已知的难以记住的值。 使用大写字母和下划线来命名这些常量

    例如,让我们以所谓的"web"(十六进制)格式为颜色声明常量:

js 复制代码
const COLOR_RED = "#F00";
const COLOR_GREEN = "#0F0";
const COLOR_BLUE = "#00F";
const COLOR_ORANGE = "#FF7F00";
// ......当我们需要选择一个颜色
let color = COLOR_ORANGE;
alert(color); // #FF7F00

好处

  1. COLOR_ORANGE 比 "#FF7F00" 更容易记忆
  2. 比起 COLOR_ORANGE 而言, "#FF7F00" 更容易输错
  3. 阅读代码时, COLOR_ORANGE 比 #FF7F00 更易懂
  • 有些常量在执行期间被"计算"出来,但初始赋值之后就不会改变。eg: const pageLoadTime = /* 网页加载所需的时间 */; pageLoadTime 的值在页面加载之前是未知的,所以采用常规命名。但是它仍然是个常量,因为赋值之后不会改变。

  • 大写命名的常量仅用作"硬编码(hard-coded)"值的别名

正确命名变量

变量名应该有清晰、明显的含义,对其存储的数据进行描述

一些可以遵循的规则:

  1. 使用易读的命名,比如 userName 或者 shoppingCart
  2. 变量名要在足够简洁的同时准确描述变量,像 data 和 value 这样的名称等于什么都没说,除非能够非常明显地从上下文知道数据和值所表达的含义
  3. 脑海中的术语要和团队保持一致。如果网站的访客称为"用户",则我们采用相关的变量命名,比如 currentUser(当前用户) 或者 newUser (新用户),而不要使用 currentVisitor (当前访问者)或者一个newManInTown(城里的新人)
  • 声明一个新的变量,而非重新赋值现有的变量

数据类型

JavaScript 中的值都具有特定的类型

可以将任何类型的值存入变量

可以重新赋值

js 复制代码
let message = "hello";
message = 123456;

Number 类型

number 类型代表整数和浮点数

"number" 类型无法表示大于 (2^53^-1) (即 9007199254740991 ),或小于-(2^53^-1) 的整数

数字可以有很多操作,比如,乘法 * 、除法 / 、加法 + 、减法 - 等等。

除了常规的数字,还包括所谓的"特殊数值"也属于这种类型:

Infinity 、 -Infinity 和 NaN

  • Infinity 代表数学概念中的 无穷大 ∞。是一个比任何数字都大的特殊值。
    我们可以通过除以 0 来得到,它或者在代码中直接使用它:
js 复制代码
alert( 1 / 0 ); // Infinity
alert( Infinity ); // Infinity
  • NaN 代表一个计算错误。它是一个不正确的或者一个未定义的数学操作所得到的结果
    NaN 是粘性的。任何对 NaN 的进一步操作都会返回 NaN
    eg:
js 复制代码
alert( "not a number" / 2 ); // NaN,这样的除法是错误的
alert( "not a number" / 2 + 5 ); // NaN

BigInt 类型

BigInt 类型用于表示任意长度的整数

通过将 n 附加到整数字段的末尾来创建 BigInt 值

js 复制代码
// 尾部的 "n" 表示这是一个 BigInt 类型
const bigInt = 1234567890123456789012345678901234567890n;

String 类型

JavaScript 中的字符串必须被括在引号里

js 复制代码
let str = "Hello";
let str2 = 'Single quotes are ok too';
let phrase = `can embed another ${str}`;

在 JavaScript 中,有三种包含字符串的方式

  1. 双引号:"Hello"
  2. 单引号:'Hello'
  3. 反引号: `Hello`
  • 双引号和单引号都是"简单"引用,在 JavaScript 中两者几乎没有什么差别
  • 反引号是 功能扩展 引号。允许我们通过将变量和表达式包装在${...}中,来将它们嵌入到字符串中,eg:
js 复制代码
let name = "John";
// 嵌入一个变量
alert( `Hello, ${name}!` ); // Hello, John!
// 嵌入一个表达式
alert( `the result is ${1 + 2}` ); // the result is 3
  • ${...} 内的表达式会被计算,计算结果会成为字符串的一部分
  • 可以在 ${...} 内放置任何东西:诸如名为 name 的变量,或者诸如 1 + 2 的算数表达式,或者其他一些更复杂的。
    注意这仅仅在反引号内有效,其他引号不允许这种嵌入
js 复制代码
alert( "the result is ${1 + 2}" );// the result is ${1 + 2}(使用双引号则不会计算 ${...} 中的内容)
  • JavaScript 中没有 character 类型。

  • 在一些语言中,单个字符有一个特殊的 "character" 类型,在 C 语言和 Java 语言中被称为"char"

    在 JavaScript 中没有这种类型。只有一种 string 类型,一个字符串可以包含零个(为空)、一个或多个字符

Boolean 类型(逻辑类型)

boolean 类型仅包含两个值: truefalse

这种类型通常用于存储表示 yes 或 no 的值:

true 意味着 "yes,正确", false 意味着 "no,不正确

js 复制代码
let nameFieldChecked = true; // yes, name field is checked
let ageFieldChecked = false; // no, age field is not checked

布尔值也可作为比较的结果:

js 复制代码
let isGreater = 4 > 1;
alert( isGreater ); // true(比较的结果是 "yes")

"null" 值

特殊的 null 值不属于上述任何一种类型

它构成了一个独立的类型,只包含 null 值:

JavaScript 中的 null 仅仅是一个代表"无"、"空"或"值未知"的特殊值

js 复制代码
let age = null;//表示 age 是未知的

"undefined" 值

undefined 的含义是 未被赋值

如果一个变量已被声明,但未被赋值,那么它的值就是 undefined :

js 复制代码
let age;
alert(age); // 弹出 "undefined"

从技术上讲,可以显式地将 undefined 赋值给变量:

js 复制代码
let age = 100;// 将值修改为 undefined
age = undefined;
alert(age); // "undefined"
  • 但是不建议这样做。通常,使用 null 将一个"空"或者"未知"的值写入变量中,而undefined 则保留作为未进行初始化的事物的默认初始值

object 类型和 symbol 类型

object 类型是一个特殊的类型

其他所有的数据类型都被称为"原始类型",因为它们的值只包含一个单独的内容(字符串、数字或者其他)

相反, object 则用于储存 数据集合 和更 复杂的实体

symbol 类型用于创建对象的唯一标识符。我们在这里提到 symbol 类型是为了完整性,但我们要在学完 object 类型后再学习它

typeof 运算符

typeof 运算符以字符串的形式返回数据类型。用于分别处理不同类型值的时候,或者快速进行数据类型检验

它支持两种语法形式:

  1. 作为运算符: typeof x
  2. 函数形式: typeof(x)
    两种形式得到的结果是一样的

对 typeof x 的调用会以字符串的形式返回数据类型:

js 复制代码
typeof(x) == "number"//运算数为数字
typeof(x) == "string"//运算数为字符串
typeof(x) == "boolean"//运算数为布尔值
typeof(x) == "object"//运算数为对象、数组和null
typeof(x) == "function"//运算数为函数
typeof(x) == "undefined"//运算数为未定义

eg:

js 复制代码
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)

最后三行的额外说明:

  1. typeof null 的结果是 "object" 。这是官方承认的 typeof 的行为上的错误,这个问题来自于 JavaScript 语言的早期,并为了兼容性而保留了下来。 null 绝对不是一个object 。 null 有自己的类型,它是一个特殊值
  2. typeof alert 的结果是 "function" ,因为 alert 在 JavaScript 语言中是一个函数。我们会在下一章学习函数,那时我们会了解到,在 JavaScript 语言中没有一个特别的 "function"类型。函数隶属于 object 类型。但是 typeof 会对函数区分对待,并返回"function" 。这也是来自于 JavaScript 语言早期的问题。从技术上讲,这种行为是不正确的,但在实际编程中却非常方便

交互:alert、prompt 和 confirm

alert

alert会显示一条信息,并等待用户按下 "OK"。 例如: alert("Hello");

弹出的这个带有信息的小窗口被称为 模态窗。"modal" 意味着用户不能与页面的其他部分(例如点击其他按钮等)进行交互,直到他们处理完窗口。在上面示例这种情况下 ------ 直到用户点击"确定"按钮

prompt

prompt 函数接收两个参数:

result = prompt(title, [default]);

浏览器会显示一个带有文本消息的模态窗口,还有 input 框和确定/取消按钮

title

title显示给用户的文本

default

default指定 input 框的初始值

  • 语法中的方括号 [...]
    上述语法中 default 周围的方括号表示该参数是可选的,不是必需的

访问者可以在提示输入栏中输入一些内容,然后按"确定"键。然后我们在 result 中获取该文本。或者他们可以按取消键或按 Esc 键取消输入,然后我们得到 null 作为 result

prompt 将返回用户在 input 框内输入的文本,如果用户取消了输入,则返回 null

举个例子:

js 复制代码
let age = prompt('How old are you?', 100);
alert(`You are ${age} years old!`); // You are 100 years old!
  • IE 浏览器会提供默认值

第二个参数是可选的。但是如果我们不提供的话,Internet Explorer 会把 "undefined" 插入到 prompt

我们可以在 Internet Explorer 中运行下面这行代码来看看效果:
let test = prompt("Test");

所以,为了 prompt 在 IE 中有好的效果,我们建议始终提供第二个参数:
let test = prompt("Test", ''); // <-- 用于 IE 浏览器

confirm

语法:
result = confirm(question);

confirm 函数显示一个带有 question 以及确定和取消两个按钮的模态窗口

点击确定返回 true ,点击取消返回 false

例如:

js 复制代码
let isBoss = confirm("Are you the boss?");
alert( isBoss ); // 如果"确定"按钮被按下,则显示 true
  • 这些方法都是模态的:它们暂停脚本的执行,并且不允许用户与该页面的其余部分进行交互,直到窗口被解除 法共有两个限制:
    1. 模态窗口的确切位置由浏览器决定。通常在页面中心
    2. 窗口的确切外观也取决于浏览器。我们不能修改它
      这就是简单的代价。还有其他一些方法可以显示更漂亮的窗口,并与用户进行更丰富的交互

类型转换

大多数情况下,运算符和函数会自动将赋予它们的值转换为正确的类型

比如, alert 会自动将任何值都转换为字符串以进行显示。算术运算符会将值转换为数字

在某些情况下,则需要将值显式地转换为期望的类型

  • 在本章中,不会讨论 object 类型。目前,将只学习原始类型
    之后,在学习完 object 类型后,将在 对象 --- 原始值转换 一章中学习对象 --- 原始值转换

字符串转换 string

当需要一个字符串形式的值时,就会进行字符串转换。

比如,alert(value)value 转换为字符串类型,然后显示这个值

我们也可以显式地调用 String(value) 来将 value 转换为字符串类型:

js 复制代码
let value = true;
alert(typeof value); // boolean

value = String(value); // 现在,值是一个字符串形式的 "true"
alert(typeof value); // string

字符串转换最明显。 false 变成 "false" , null 变成 "null" 等

数字型转换 number

在算术函数和表达式中,会自动进行 number 类型转换。

比如,当把除法 / 用于非 number 类型:

js 复制代码
alert( "6" / "2" ); // 3, string 类型的值被自动转换成 number 类型后进行计算

我们也可以使用 Number(value) 显式地将这个 value 转换为 number 类型

js 复制代码
let str = "123";
alert(typeof str); // string
let num = Number(str); // 变成 number 类型 123
alert(typeof num); // number

当我们从 string 类型源(如文本表单)中读取一个值,但期望输入一个数字时,通常需要进行显式转换

如果该字符串不是一个有效的数字,转换的结果会是 NaN 。例如:

js 复制代码
let age = Number("an arbitrary string instead of a number");
alert(age); // NaN,转换失败

number 类型转换规则:

变成......
undefined NaN
null 0
truefalse 1 and 0
string 去掉首尾空格后的纯数字字符串中含有的数字。如果剩余字符串为空,则转换结果为 0 。否则,将会从剩余字符串中"读取"数字。当类型转换出现 error 时返回 NaN

eg:

js 复制代码
alert( Number(" 123 ") ); // 123
alert( Number("123z") ); // NaN(从字符串"读取"数字,读到 "z" 时出现错误)
alert( Number(true) ); // 1
alert( Number(false) ); // 0
  • 注意 nullundefined 在这有点不同: null 变成数字 0undefined 变成 NaN 大多数数学运算符也执行这种转换,将在下一节中进行介绍

布尔型转换 boolean

发生在逻辑运算中(将进行条件判断和其他类似的东西),也可以通过调用Boolean(value) 显式地进行转换

转换规则如下:

变成......
0 , null , undefined , NaN , " "(只有空格的字符串) false
其他值 true

eg:

js 复制代码
alert( Boolean(1) ); // true
alert( Boolean(0) ); // false
alert( Boolean("hello") ); // true
alert( Boolean("") ); // false
  • 请注意:包含 0 的字符串 "0" 是 true
    一些编程语言(比如 PHP)视 "0" 为 false 。但在 JavaScript 中,非空的字符串总是true
js 复制代码
alert( Boolean("0") ); // true
alert( Boolean(" ") ); // 空白,也是 true(任何非空字符串都是 true)

基础运算符,数学

术语:"一元运算符","二元运算符","运算元"

  • 运算元 ------ 运算符应用的对象。比如说乘法运算 5 * 2 ,有两个运算元:左运算元 5 和右运算元 2 。
    有时候也称其为"参数"而不是"运算元"。
  • 如果一个运算符对应的只有一个运算元 ,那么它是 一元运算符。比如说一元负号运算符 - ,它的作用是对数字进行正负转换:
js 复制代码
let x = 1;
x = -x;
alert( x ); // -1,一元负号运算符生效
  • 如果一个运算符拥有两个运算元,那么它是 二元运算符:
js 复制代码
let x = 1, y = 3;
alert( y - x ); // 2,二元运算符减号做减运算

数学

支持以下数学运算:

加法 + ,

减法 - ,

乘法 * ,

除法 / ,

取余 % ,

求幂 ** .

% 和 ** 需要详细说明

取余 %

取余运算符是 % ,尽管它看起来很像百分数,但实际并无关联

a % b 的结果是 a 整除 b 的 余数

例如:

js 复制代码
alert( 5 % 2 ); // 1,5 除以 2 的余数
alert( 8 % 3 ); // 2,8 除以 3 的余数

求幂 **

求幂运算 a ** b 是 a 乘以自身 b 次

例如:

js 复制代码
alert( 2 ** 2 ); // 4 (2 * 2,自乘 2 次)
alert( 2 ** 3 ); // 8 (2 * 2 * 2,自乘 3 次)
alert( 2 ** 4 ); // 16 (2 * 2 * 2 * 2,自乘 4 次)

求幂的定义也适用于非整数。例如,平方根是以 1/2 为单位的求幂:

js 复制代码
alert( 4 ** (1/2) ); // 2(1/2 次方与平方根相同)
alert( 8 ** (1/3) ); // 2(1/3 次方与立方根相同)

用二元运算符 + 连接字符串

通常,加号 + 用于求和

但是如果加号 + 被应用于字符串,它将合并(连接)各个字符串:

js 复制代码
let s = "my" + "string";
alert(s); // mystring

注意:只要任意一个运算元是字符串,那么另一个运算元也将被转化为字符串。

js 复制代码
alert( '1' + 2 ); // "12"
alert( 2 + '1' ); // "21"
相关推荐
m0_7482361118 分钟前
Calcite Web 项目常见问题解决方案
开发语言·前端·rust
Watermelo61730 分钟前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
m0_7482489432 分钟前
HTML5系列(11)-- Web 无障碍开发指南
前端·html·html5
m0_7482356143 分钟前
从零开始学前端之HTML(三)
前端·html
一个处女座的程序猿O(∩_∩)O3 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
hackeroink6 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者7 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-8 小时前
验证码机制
前端·后端
燃先生._.9 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js