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" 类型无法表示大于 (253-1) (即 9007199254740991 ),或小于-(253-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 类型仅包含两个值: true 和 false

这种类型通常用于存储表示 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
true 和 false 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
  • 注意 null 和 undefined 在这有点不同: null 变成数字 0 , undefined 变成 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"
相关推荐
RobinDevNotes10 分钟前
从 Electron 到 GPUI,9 个跨平台桌面方案该怎么选
前端·javascript·rust·electron·openresty·前端开发工具
jay神1 小时前
基于 YOLOv8 的轴承缺陷检测(Web 版)
前端·人工智能·yolo
jay神1 小时前
基于 YOLOv8 的森林火灾检测系统(Web 版)
前端·yolo
code2cat1 小时前
HTML基础篇之第一张网页:从index.html到浏览器里的任务清单
前端·html
miss2 小时前
AI 改完不敢上线?OpenSpec 规约驱动开发实战
前端·代码规范·前端工程化
AiMan3 小时前
腾讯ima还是不可以导出左侧所有对话,只能单条导出,方法不对吗
前端
去伪存真3 小时前
并发量一高就装死?Agent 全链路“防猝死”手册
前端·agent
Moment3 小时前
AI 编程时代,聊聊我的 Mac mini 双屏桌面
前端·后端
AiMan3 小时前
先确认能不能一次把Microsofat Copilot所有内容打包一个文件导出
前端
总要学点什么3 小时前
第97篇:三维数据加载-城市建筑白模自定义着色器——让一条光带沿高度扫上去,快慢却由帧率说了算
前端·gis·webgl·cesium·着色器·空间分析·白模