目录
- 1、JavaScript入门
-
- [1.1 打开Web中的控制台](#1.1 打开Web中的控制台)
- [1.2 输入并运行JavaScript](#1.2 输入并运行JavaScript)
- [1.3 输入多行JavaScript代码](#1.3 输入多行JavaScript代码)
- [1.4 严格模式](#1.4 严格模式)
- [2. 语法和类型](#2. 语法和类型)
-
- [2.1 基础](#2.1 基础)
- [2.2 注释](#2.2 注释)
- [2.3 变量声明方式](#2.3 变量声明方式)
- [2.4 变量命名规则](#2.4 变量命名规则)
- [2.5 初始化](#2.5 初始化)
- [2.6 变量作用域](#2.6 变量作用域)
- [2.7 变量提升](#2.7 变量提升)
- [2.8 全局变量](#2.8 全局变量)
- [2.9 常量](#2.9 常量)
- [2.10 数据结构和类型](#2.10 数据结构和类型)
-
- [2.10.1 基本数据类型](#2.10.1 基本数据类型)
- [2.10.2 数据类型的转换](#2.10.2 数据类型的转换)
- [2.10.3 数字和"+"运算符](#2.10.3 数字和"+"运算符)
- [2.10.4 字符串转换为数字](#2.10.4 字符串转换为数字)
- [2.10.5 字面量](#2.10.5 字面量)
-
- [2.10.5.1 数组字面量](#2.10.5.1 数组字面量)
- [2.10.5.2 布尔字面量](#2.10.5.2 布尔字面量)
- [2.10.5.3 数字字面量](#2.10.5.3 数字字面量)
-
- [2.10.5.3.1 整数字面量](#2.10.5.3.1 整数字面量)
- [2.10.5.3.2 浮点数字面量](#2.10.5.3.2 浮点数字面量)
- [2.10.5.4 对象字面量](#2.10.5.4 对象字面量)
-
- [2.10.5.4.1 增强的对象字面量](#2.10.5.4.1 增强的对象字面量)
- [2.10.5.5 RegExp字面量](#2.10.5.5 RegExp字面量)
- [2.10.5.6 字符串字面量](#2.10.5.6 字符串字面量)
-
- [2.10.5.6.1 特殊字符](#2.10.5.6.1 特殊字符)
- [2.10.5.6.2 转义字符](#2.10.5.6.2 转义字符)
- 参考
- 待了解
1、JavaScript入门
1.1 打开Web中的控制台
edge浏览器按下F12。控制台界面如下:

1.2 输入并运行JavaScript
. 在控制台界面(如图)中输入console.log(eval(3 + 5))


1.3 输入多行JavaScript代码
代码如下:
javascript
(function () {
"use strict";
/* 代码开始 */
function greetMe(yourName) {
alert(`你好${yourName}`);
}
greetMe("世界");
/* 代码结束 */
})();

1.4 严格模式
始终使用如下的代码:
javascript
(function () {
"use strict";
/* 代码开始 */
/* 代码结束 */
})();
2. 语法和类型
2.1 基础
JavaScript是区分大小写的,并使用Unicode字符集。
javascript
const Fruh = "foobar";
因此上面的变量Fruh和fruh是两个不同的变量。
在JavaScript中,指令被称为语句,并用分号分隔。如果一条语句独占一行的话,分号是可以省略。但如果一行中有多条语句,那么这些语句必须用分号进行分隔。

建议在每条语句的末尾加上分号。
从左往右扫描JavaScript脚本的源文本并将其转换为输入元素(token、控制字符、行终止符、注释和空白字符,空白字符指的是空格、制表符和换行符等)序列。
2.2 注释
单行注释和多行注释如下:
javascript
// 单行注释
/* 这是一个更长的,
* 多行注释
*/
不能在注释中出现*/,必须插入反斜杠进行转义*\/。
此外,还可以在JavaScript文件的开头见到像#!/usr/bin/env node这样的注释,这是hashbang注释语法,用于指定执行脚本的特定JavaScript引擎路径。
2.3 变量声明方式
| 关键字 | 作用 |
|---|---|
| var | 声明一个变量(局部或全局变量),可选择将其初始化为一个值 |
| let | 声明一个块级作用域的局部变量,可选择将其初始化为一个值 |
| const | 声明一个块级作用域的只读命名常量 |
2.4 变量命名规则
变量的名字叫标识符,通常以字母、下划线或者美元符号开头,后续的字符还可以是数字。此外,还可以在标识符中使用大部分Unicode字母。
在声明后使用变量。
2.5 初始化
在let x = 42中let x称作声明,= 42称作初始化器。未声明访问变量会抛出ReferenceError,初始化器会给变量赋值。在var和let声明中,初始化器是可选的。

如果声明变量时没有进行初始化,变量会被赋值为undefined。

const声明总是需要初始化器,因为禁止在声明后进行任何类型的赋值,以及隐式地将其初始化为undefined。

2.6 变量作用域
| 作用域 | 描述 |
|---|---|
| 全局作用域 | 在脚本模式中运行的所有代码的默认作用域 |
| 模块作用域 | 在模块模式中运行的代码的作用域 |
| 函数作用域 | 由函数创建的作用域 |
| 块级作用域 | 用一对花括号创建的作用域 |
在函数外部声明变量时,该变量为全局变量;在函数内声明变量时,为局部变量。
let和const声明被限制在声明所在的块语句中。
javascript
if (Math.random() > 0.5) {
const y = 5;
}
console.log(y);

用var创建的变量不是块级的,而是块所在函数或全局作用域的。
javascript
if (true) {
var x = 5;
}
console.log(x);

2.7 变量提升
用var声明的变量会被提升,也就是该变量所在的作用域的任何地方引用该变量,即使还没有到达该变量声明的地方。如果在声明该变量之前访问该变量,其值总是undefined。
javascript
console.log(x == undefined);
var x = 3;
(function () {
console.log(x);
var x = "局部值";
})();

上面的例子可以被解释为:
javascript
var x;
console.log(x == undefined);
x = 3;
(function () {
var x;
console.log(x);
x = "局部值";
})();
由于存在变量提升,一个函数中所有的var语句应尽可能地放在接近函数顶部的地方。
在变量声明之前引用块中的变量,将总是抛出ReferenceError,因为该变量处于从块开始到声明所在的"暂时性死区"中。
javascript
console.log(x);
const x = 3;

与var声明不同,函数声明是全部被提升的,可以在该函数的作用域中的任何地方安全地调用函数。
2.8 全局变量
全局变量是全局对象的属性。在网页中,全局对象是window,可以用window.variable语法读取和设置全局变量。

在所有的环境中,globalThis变量也是全局变量,可以用于读取和设置全局变量。

可以通过制定window或frame的名字,在当前window或frame访问另一个window或frame中声明的变量。如果在window中声明了一个叫phoneNumber的全局变量,就可以在iframe中使用parent.phoneNumber引用它。
2.9 常量
可以用const关键字创建一个只读命名常量。常量标识符要求和变量标识符一致,必须以字母、下划线或美元符号开头并可以包含字母、数字或下划线。
javascript
const PI = 3.14;
常量不可以通过赋值来改变其值或在脚本运行时被重新声明。必须为其初始化一个值。常量的作用域规则和let块级作用域变量一致。在同一作用域中,不能使用与变量名或函数名相同的名字来声明常量。
javascript
function f() {}
const f = 5;

const仅阻止重新赋值,而不阻止修改。被赋值为常量的对象的属性是不受保护,所以下面的语句执行时不会产生错误。
javascript
const MY_OBJECT = { key: "值" };
MY_OBJECT.key = "其他值";

2.10 数据结构和类型
2.10.1 基本数据类型
| 关键字 | 含义 |
|---|---|
| Boolean | true | false |
| null | 一个表示空值的特殊关键字 |
| undefined | 一个未定义值的顶级属性 |
| Number | 整数或浮点数 |
| BigInt | 任意精度的整数 |
| String | 表示文本值的字符序列 |
| Symbol | 实例是唯一且不可变的数据类型 |
| Object |
2.10.2 数据类型的转换
JS是一门动态类型语言,在声明变量时可以不必指定该变量的数据类型,在脚本执行期间会根据需要自动转换数据类型。
javascript
let answer = 42;
answer = "不客气,感谢所有的鱼!";

2.10.3 数字和"+"运算符
在使用+运算符的表达式中涉及数字和字符串,JS会把数字转换成字符串。
javascript
x = "答案是 " + 42; // "答案是 42"
y = 42 + " 是答案"; // "42 是答案"
z = "37" + 7; // "377"
在使用其他运算符时,JS不会把数字转换成字符串。
javascript
"37" - 7; // 30
"37" * 7; // 259
2.10.4 字符串转换为数字
parseInt只返回整数。最佳实践是带上进制参数。
javascript
parseInt("101", 2) // 5

将字符串转换为数字的另一种方法是使用+(一元加)运算符。
javascript
"1.1" + "1.1" = "1.11.1"
+"1.1" + +"1.1" = 2.2
2.10.5 字面量
在JS中,字面量可以表示值。这些字面量是脚本中按字面意思给出的固定的值,而不是变量。
2.10.5.1 数组字面量
数组字面量是由一对方括号括起来的包含零个或多个表达式的列表,其中每个表达式代表一个数组元素。该数组会以指定的值作为其元素进行初始化,而其length被设定为指定参数的个数。
javascript
const coffees = ["French Roast", "Colombian", "Kona"];
coffees.length;

每次字面量被求值的时候,数组字面量都会创建一个新的数组对象。例如,在全局作用域中用字面量定义的数组在脚本加载后被创建;如果数组字面量位于函数内,每次调用函数都会初始化一个新数组。
在数组字面量中连续放置两个逗号,数组会为未指定的元素留下一个空槽。
javascript
const fish = ["Lion", , "Angel"];
fish;

第二项是"empty",与实际的undefined不同。当使用数组遍历方法时,空槽会被跳过。通过索引访问fish[1]仍会返回undefined。在元素列表的尾部添加了一个逗号,它将会被忽略。
javascript
const myList = ["home", , "school",];
myList;

在书写时,显示地将缺失的元素声明为undefined,或者至少插入一个注释以突出元素缺失。这样能提高代码的清晰度和维护性。
const list = ["home", undefined, "school", undefined];
list;

2.10.5.2 布尔字面量
布尔类型有两种字面量值:true和false。
不要将原始布尔值true和false与Boolean对象的真和假弄混。
2.10.5.3 数字字面量
JS数字字面量包含多种基数的整数字面量和以10为基数的浮点数字面量。数字字面量必须是无符号的。-123。4会被解释为一元操作符-应用于数字字面量123.4。
2.10.5.3.1 整数字面量
整数和BigInt字面量可以用十进制、十六进制、八进制和二进制表示。
| 类型 | 要求 |
|---|---|
| 十进制整数 | 由数字序列构成,没有前缀0 |
| 八进制整数 | 以0或0O、0o开头,只能包含0-7 |
| 十六进制整数 | 以0x或0X开头,包含0-9和a-f或A-F(字符的大小写不影响数值) |
| 二进制整数 | 以0b或0B开头,只能包含0、1 |
| BigInt | 由整数字面量和n后缀组成。可以上面的类型,但是0123n不允许 |
javascript
0, 117, 123456789123456789n
015, 0001, 0o7777777777777n
0x1123, 0x00111, 0x123456789ABCDEFn
0b11, 0b0011, 0b11101010101010101n
2.10.5.3.2 浮点数字面量
浮点数字面量由一个无符号的十进制整数、小数点、小数部分(另一个十进制数)和指数部分组成。指数部分以e或E开头,后面跟着一个整数,这个整数可以有正负号。浮点数字面量至少有一位数字,而且必须带小数点或者e(E)。
其语法是:[digits].[digits][(E|e)[(+|-)]digits]。
javascript
3.1415926
.123456789
3.1E+12
.1e-23
2.10.5.4 对象字面量
对象字面量是由一对花括号括起来的包含零个或者多个属性名和相关值的列表。
javascript
const sales = "Toyota";
function carTypes(name) {
return name === "Honda" ? name : `对不起,我们不售卖 ${name}。`;
}
const car = { myCar: "Saturn", getCar: carTypes("Honda"), special: sales }; // object
console.log(car.myCar);
console.log(car.getCar);
console.log(car.special);

可以使用数字或字符串字面量作为属性的名字,或者在另一个对象字面量内嵌套一个对象字面量。
javascript
const car = { manyCars: { a: "Saab", b: "Jeep" }, 7: "Mazda" };
console.log(car.manyCars.b);
console.log(car[7]);

对象属性名字可以是任意字符串,包括空串。如果对象属性名字不是合法的JavaScript标识符或数字,它必须用引号包裹。属性不合法,便不能用点访问属性值。
javascript
const unusualPropertyNames = {
'': '空字符串',
'!': '砰!'
}
console.log(unusualPropertyNames.'');
console.log(unusualPropertyNames.!);

而是通过方括号表示法来访问。
javascript
console.log(unusualPropertyNames[""]);
console.log(unusualPropertyNames["!"]);

2.10.5.4.1 增强的对象字面量
对象字面量支持一组简写语法,包括在创建时设置原型、foo: foo赋值的简写、定义方法、支持super调用以及使用表达式计算属性名。
javascript
const obj = {
// __proto__
__proto__: theProtoObj,
// "handler: handler"的简写
handler,
// 方法
toString() {
// Super调用
return "d " + super.toString();
},
// 计算动态属性名
["prop_" + (() => 42)()]: 42,
};
2.10.5.5 RegExp字面量
一个正则表达式字面量是字符被斜杠围成的表达式。
javascript
const re = /ab+c/;
2.10.5.6 字符串字面量
字符串字面量是由一对双引号或单引号括起来的零个或多个字符。字符串被限定在同种引号之间。
javascript
'foo'
"bar"
'1234'
'一行\n另一行'
"Joyo 的猫"
可以在字符串字面量值上使用String对象的素有方法。JS会自动将字符串字面量转换为一个临时字符串对象,调用该方法,然后废弃那个临时字符串对象。
javascript
console.log("John 的猫".length);

模板字面量由一对反引号包围。
javascript
`在 JavaScript 中,"\n" 是换行符。`
`在 JavaScript 中,模板字符串可以
跨越行,但是由双引号和单引号
包裹的字符串不行。`
const name = 'Lev', time = 'today';
`你好 ${name},${time} 过得怎么样!`
带标签的模板是用于指定模板字面量并调用"标签"函数解析模板字面量的紧凑语法。
javascript
const formatArg = (arg) => {
if (Array.isArray(arg)) {
return arg.map((part) => `- ${part}`).join("\n");
}
if (arg.toString === Object.prototype.toString) {
return JSON.stringify(arg)
}
return arg;
}
const print = (segments, ...args) => {
let message = segments[0];
segments.slice(1).forEach((segment, index) => {
message += formatArg(args[index]) + segment;
});
console.log(message);
};
const todos = ["学习 JavaScript", "学习 Web API", "构建网站", "利润!"];
const progress = { javascript: 20, html: 50, css: 10 };
print`我需要做:
${todos}
当前进度为:${progress}
`;
/*
print`我需要做:
${todos}
当前进度为:${progress}
` => print(["我需要做:\n", "当前进度为", "\n"], [todos, progress])
=> message = "我需要做:\n"
=> segments.slice(1) => ["当前进度为", "\n"]
=> forEach循环 第一次 segment = "当前进度为" index = 0 args[0] = todos
=> "我需要做:\n" + (formatArg(todos: Array) + "当前进度为")
=> "我需要做:\n" + "\n".join(["- 学习 JavaScript", "- 学习 Web API", "- 构建网站", "- 利润!"]) + "当前进度为"
=> message = "我需要做:\n- 学习 JavaScript\n- 学习 Web API\n- 构建网站\n- 利润!\n当前进度为"
=> forEach循环 第二次 segment = "\n" index = 1 args[1] = progress
=> message + (formatArg(progress: Object) + segment)
=> message + '{"javascript": 20, "html": 50, "css": 10}' + "\n"
=> message = '我需要做:\n- 学习 JavaScript\n- 学习 Web API\n- 构建网站\n- 利润!\n当前进度为{"javascript": 20, "html": 50, "css": 10}\n'
*/

2.10.5.6.1 特殊字符
| 字符 | 意思 |
|---|---|
| \0 | 空字节 |
| \b | 退格符 |
| \f | 换页符 |
| \n | 换行符 |
| \r | 回车符 |
| \t | 制表符 |
| \v | 垂直制表符 |
| ' | 撇号或单引号 |
| " | 双引号 |
| \ | 反斜杠字符 |
| \XXX | 由从0到377最多三位八进制数XXX表示的Latin-1字符 |
| \xXX | 由从00和FF的两位十六进制数字XX表示的Latin-1字符 |
| \uXXXX | 由四位十六进制数字XXX表示的Unicode字符 |
| \u{XXXXX} | Unicode码位转义 |
2.10.5.6.2 转义字符
javascript
const quote = "He read \"The Cremation of Sam McGee\" by R.W. Service.";
console.log(quote);

javascript
const home = "c:\\temp";
console.log(home);

可以在换行之前加上反斜杠以转义换行。这样反斜杠和换行都不会出现在字符串的值中。
javascript
const str =
"this string \
is broken \
across multiple \
lines.";
console.log(str);

参考
2、语法和类型
待了解
1、严格模式
4、Array
5、索引集合
6、Boolean
7、正则表达式
8、String