后端:Java Web后端要点简记:Java & JVM、Spring、Spring MVC与Spring Boot
数据库与缓存:Java Web数据库与缓存要点整理:MySQL、Redis、Spring Data与MyBatis
HTML与CSS
HTML标签语义可以查阅MDN Web Docs - HTML 元素参考。
CSS样式与排版可以查阅MDN Web Docs - 基本文本和字体样式。
HTML与CSS部分要点
HTML对大小写不敏感,甚至可以混写。
CSS有三种引入方式:
行内样式:在HTML标签的
style
属性中指定,作用于此标签。不易维护。例如:1
<div style="color: #FFDD44; font-weight: bold;">天馬咲希</div>
内嵌样式:在页面的
style
标签中指定,作用于页面。通常在head
标签中引入,但放在页面的任何地方均可。例如:1
2
3
4
5
6
7
8<style>
miku {
color: #33CCBB;
font-weight: bold;
}
</style>
<miku>初音ミク</miku>外联样式:在单独的css文件中指定。需要页面通过
link
标签引入(通常引入在head
标签中)。例如:1
2
3
4ick {
color: #33AAEE;
font-weight: bold;
}引入:
1
2
3
4
5<head>
<link rel="stylesheet" href="./ick.css">
</head>
<ick>星乃一歌</ick>
CSS有三种选择器,分别为
元素选择器:根据标签名称选择样式,例如上文设置的ick标签样式
id选择器:根据id属性选择样式,在一个页面中id不可重复。例如
1
2
3
4
5
6
7
8<style>
#shiho {
color: #EE6666;
font-weight: bold;
}
</style>
<span id="shiho">望月穂波</span>类选择器:根据class属性选择样式,在一个页面中class可重复。例如
1
2
3
4
5
6
7
8<style>
.hnm {
color: #BBDD22;
font-weight: bold;
}
</style>
<span class="hnm">日野森志歩</span>
优先级:1. id选择器;2. 类选择器;3. 元素选择器
两个没有语义的标签:
div标签
一行仅显示一个div块,即独占一行,后续内容会从下一行开始
宽度默认为父元素的宽度,高度默认由内容撑开
可以设置width与height
可以设置盒子的所有参数:
1
2
3
4
5
6
7
8
9
10<style>
div {
width: 200px;
height: 200px;
box-sizing: border-box; /* 指定width、height为盒子的宽与高 */
padding: 20px 20px 20px 20px; /* 分别为上、右、下、左 */
border: 10px solid red; /* 宽度,线条类型,颜色 */
margin: 30px 30px 30px 30px; /* 同上 */
}
</style>要实现所有文本全部居中显示,可以用大div块将正文全部纳入:
1
2
3
4
5<div style="widthh: 65%;margin: 0 auto">
仅指定了两个值,分别对应上下外边距与左右外边距,这里上下外边距为0,让浏览器自动计算左右外边距,即各一半<br>
如果指定三个值,则分别对应上外边距、右外边距、下外边距<br>
如果制定一个值,则该值同时作为上外边距、右外边距、下外边距与左外边距
</div>span标签
- 一行可以显示多个,即不会独占一行,后续内容会从span块后开始
- 宽度与高度默认由内容撑开
- 不可设置width与height
表格标签<table>
可以包裹多个表格的行<tr>
:具有表格边框宽度属性border
,表格宽度属性width
,单元之间的空间cellspacing
- 表格的行
<tr>
可以包裹多个普通表格单元格<td>
- 普通表格单元格
<td>
:如果是表头单元格,可以替换为<th>
,默认带有加粗、居中效果
- 普通表格单元格
表单标签<from>
,有若干属性:
action
:规定当提交表单时向何处发送表单数据(URL,uniform resource locator,统一资源定位系统)method
:规定用何种方式发送表单数据(常见GET、POST),默认为GET
表单中又有不同的表单项,分别由几个不同的标签代表
<input>
:定义表单项,通过type
属性控制输入形式(默认值text
单行输入字段,password
密码字段、radio
单选按钮(添加check
默认选择)、checkbox
复选框、file
文件上传按钮、date
/time
/datetime-local
日期/时间/日期时间,number
数字输入框,email
邮件输入框,hidden
隐藏域,submit
/reset
/button
提交按钮/重置按钮/可点击按钮),通过name
属性命名(必须要有该属性才能提交),通过placeholder
属性指定默认文本,通过value
属性指定表单提交时的值。给按钮加上
<label>
标签,点击按钮标签内的文字时也会选上按钮。<select>
:定义下拉列表,通过potion
属性定义列表项,通过value
属性指定表单提交时的值。<textarea>
:定义文本域
1 | <form action="" method="get"> |
GET的内容紧随URL之后,以?
起始,以&
连结,长度被浏览器限制;POST在消息体(请求体)中传递,在Chrome中可通过F12
-> Network -> Payload(载荷)查看。
JavaScript
JavaScript是一门跨平台、面向对象的脚本语言,可以在前端控制网页行为,定义交互。JavaScript遵守ECMAScript标准。
不同浏览器内核使用不同的JavaScript引擎实现,这导致部分API行为可能存在差异。例如Chrome所采用的V8引擎更严格地遵循了ECMAScript标准,典型表现为parseInt("")
返回NaN
,而Firefox所采用的SpiderMonkey引擎在旧版本中parseInt("")
将返回0
,不过这一问题在当前的新版本中已修复。
本文作于2025年。请核对JavaScript引擎版本。
引入方式
- JavaScript代码必须位于
<script>
与</script>
标签对之间 - 脚本可置于文档任意位置且可置于文件任意次数,但最佳实践为:
- 放置于
<body>
结束标签(</body>
)之前 - 优化原理:传统同步脚本会阻塞DOM解析与渲染(现代浏览器支持
async/defer
属性优化) - 例外场景:需提前执行的脚本可置于
<head>
,但必须配合defer
属性
- 放置于
外部文件需满足:
- 扩展名为
.js
- 仅包含纯JavaScript代码(不含HTML标签)
- 扩展名为
引入语法:
1
2
3
4
5<!-- 标准引入方式 -->
<script src="path/to/script.js"></script>
<!-- 特别注意:错误示范(自闭标签无效) -->
<script src="error.js" />模块化规范:ES6+ 推荐使用
type="module"
声明模块脚本
语法基础规范
设计影响:JavaScript初期语法设计受Java启发(实则碰瓷Java,与Java天差地别)
本质差异:
- 动态弱类型 vs 静态强类型
- 基于原型的继承 vs 基于类的继承
- 解释执行 vs 编译执行
语句终止符(“;”)
显式分号:推荐始终使用
;
作为语句终止符ASI机制(Automatic Semicolon Insertion):
换行符可能触发自动分号插入
高危场景:
1
2return
{ a: 'a' }; // 被解析为 return; { a: 'a' };
与Go语言差异:
- Go采用严格词法分析,分号插入规则无歧义
- JavaScript ASI存在语义解析风险,因此更推荐以显式分号结束语句
注释规范
单行注释:
// 注释内容
多行注释:
/* 注释内容 */
文档注释(JSDoc):
1
2
3
4
5/**
* 函数功能描述
* @param {type} paramName 参数说明
* @returns {returnType} 返回值说明
*/
代码块界定
- 使用花括号
{}
定义代码块作用域 - 注意:无块级作用域的
var
声明存在变量提升(Hoisting)
在ECMAScript
5中引入了一个JavaScript特性——严格模式,旨在通过更严格的语法规则和错误检查机制以消除代码中的潜在风险。严格模式的主要内容有变量必须显式声明、禁止删除不可删除的属性、严格语法(禁止重复的函数参数名、八进制数字必须规范使用0o......
表示等)、全局作用域下this
指向undefined
而非非严格模式下的window
、禁用with
语句等等。
要全局启用严格模式,在内部脚本或外部脚本第一行添加"use strict";
指令即可;在函数体的第一行添加"use strict";
则可以仅在函数内部启用严格模式。MAScript
6模块(例如使用import
、export
语法)自动启用严格模式。
标准输出方法
方法 | 作用域 | 输出目标 | 使用场景 |
---|---|---|---|
window.alert(message) 可简写为 alert(message) |
浏览器窗口 | 模态警告框 | 调试警告信息 |
document.write(content) |
DOM流 | HTML文档体 | 已弃用(破坏DOM结构) |
console.log(message) |
DevTools | 控制台 | 调试日志 |
在ECMAScript
6标准中,推荐使用模板字符串进行字符串插值,支持自然格式书写(无需使用换行符,类似HTML中<pre>
标签的效果),语法为以`
起始、以`
结束、在内部通过${expression}
语法标识需要嵌入的变量或表达式。例如:
1 | var name = '天馬咲希'; |
变量声明机制
JavaScript不需要显式指明变量的数据类型,JavaScript解释器会自行推导,这一点类似Python。
var
声明(ES5)
作用域:函数作用域或全局作用域
特性:
允许重复声明(导致变量覆盖)
存在变量提升(声明提升至作用域顶端)
示例:
1
2console.log(a); // undefined(变量提升)
var a = 10;
let
声明(ES6+)
作用域:严格块级作用域(
{}
内有效)特性:
禁止重复声明(SyntaxError)
暂时性死区(TDZ)限制
示例:
1
2
3
4if (true) {
let b = 20;
}
console.log(b); // ReferenceError
const
声明(ES6+)
作用域:块级作用域
特性:
必须立即初始化
禁止重复赋值(原始类型不可变)
对象类型可修改内容(内存地址不变):
1
2
3const obj = { prop: 1 };
obj.prop = 2; // 允许
obj = {}; // TypeError深度冻结:
Object.freeze(obj)
数据类型
JavaScript可以通过typeof
关键字获取数据类型,例如alert(typeof 3.14);
、alert(typeof '天馬咲希')
。
原始类型(Primitive Types)
类型 | 示例 | 特性 |
---|---|---|
number |
3.14 , NaN ,
Inf |
双精度浮点数(IEEE
754标准),NaN 意为Not-a-Number |
string |
"text" ,
'text' |
UTF-16编码,不可变序列 |
boolean |
true ,
false |
严格布尔逻辑 |
null |
null |
表示空对象引用(typeof为Object ) |
undefined |
undefined |
未初始化变量默认值 |
symbol |
Symbol('desc') |
ES6+唯一标识符 |
在ECMAScript标准中,null
本应是一种原始类型,但typeof null
返回的却不是Null
而是Object
。实际上,这是JavaScript早期的一个漏洞,但被ECMAScript沿用了,因此便一直保留在了JavaScript。现在null
也可以被解释为对象的占位符,但就技术标准而言,Null
才是原始类型。
对象类型(Object Types)
对象(Object)及其派生类型,包括
Array
,Function
,Date
,RegExp
等存储特性:变量存储内存地址引用
类型转换
函数/方法 | 转换目标类型 | 处理机制 | 示例 | 注意事项 |
---|---|---|---|---|
parseInt(string, radix) |
number |
1).
原始类型直接转为字符串后解析整数部分 2). 对象类型调用 toString() 后再视为原始类型解析 |
parseInt("123px") → 123 parseInt({}) → NaN ({} 转字符串为[object Object] ) |
parseInt 会从字符串首字符开始匹配直至首个非数字位停止,如果首字符非数字则解析失败并返回NaN ,空字符串可能返回NaN (部分浏览器返回0 ) |
Number(value) |
number |
1). 原始类型按规则转换 2). 对象类型先调用 valueOf() ,失败则调用toString() |
Number("3.14") → 3.14 Number([1]) → 1 (数组转字符串后解析) |
null 转0 ,undefined 转NaN ,空数组转0 ([] 转字符串为
"" → 0 ) |
String(value) |
string |
1). 原始类型直接转为字符串 2). 对象类型调用 toString() |
String(42) → "42" String({}) → "[object Object]" |
null 转"null" ,undefined 转"undefined" |
Boolean(value) |
boolean |
1). 原始类型按假值规则转换 2). 对象类型始终转 true (包括空对象/数组) |
Boolean("") → false Boolean([]) → true |
假值包括:0 、NaN 、"" 、null 、undefined ,非空字符串恒为真值,除0 与NaN 的数字恒为真值;if() 会隐式调用Boolean() 将非布尔值转换为布尔值 |
parseFloat(string) |
number |
1). 原始类型转为字符串后解析浮点数 2). 对象类型调用 toString() 后解析 |
parseFloat("3.14px") → 3.14 parseFloat([2.5]) → 2.5 |
不支持进制参数,指数形式(如3e5 )可解析 |
Object(value) |
object |
1). 原始类型转为包装对象(如
Number 、String )2). 对象类型直接返回 |
Object(42) → Number {42} Object("text") → String {"text"} |
null /undefined 转空对象({} ) |
Symbol.description |
string |
仅限Symbol 类型,返回符号描述字符串 |
Symbol('desc').description → "desc" |
非Symbol 类型调用会报错 |
toString() |
string |
1).
原始类型转为字符串(null /undefined 无此方法)2). 对象类型返回实现定义值 |
(123).toString() → "123" [1,2].toString() → "1,2" |
对象默认返回[object Object] ,数组以逗号拼接元素 |
valueOf() |
原始值 | 1). 原始类型返回自身 2). 对象类型尝试返回原始值(失败则返回对象本身) |
new Date().valueOf() → 时间戳 {}.valueOf() → {} |
参与运算时优先调用此方法(如obj + 1 ) |
运算符与操作符
JavaScript中应当支持短路机制的运算符、操作符基本上均支持短路机制。
运算符(Operators)
对于具有JavaScript特色而在其他编程语言中不常见的运算符将标注其名称并对其中需要说明的在后文中解释,在其他编程语言设计中常见的操作符不再赘述。
- 算术运算符:
+
,-
,*
,/
,%
,**
,++
,--
- 赋值运算符:
=
,+=
,-=
,*=
,/=
,%=
,**=
,&&=
,||=
,??=
(空值合并赋值) - 比较运算符:
>
,<
,>=
,<=
,==
(宽松相等),!=
,===
(严格相等),!==
- 逻辑运算符:
&&
,||
,!
,??
(空值合并) - 位运算符:
&
,|
,~
,^
,<<
,>>
,>>>
(无符号右移动) - 三元运算符:条件表达式
condition ? expr1 : expr2
- 展开运算符:
...
辨析==
与===
、!=
与!==
:对于原始类型,==
会在进行隐式类型转换后再比较值,===
则不会进行隐式类型转换而是直接比较。这意味着666 == "666"
的值为true
,而666 === "666"
的值为false
。然而,对于对象类型,==
与===
均直接比较内存地址,因此["天馬咲希", ...["星乃一歌"]] == ["天馬咲希", "星乃一歌"]
的值为false
。
null、underfined与NaN在相等判断下的行为及两两比较
比较表达式 | == 结果 |
=== 结果 |
说明 |
---|---|---|---|
null == undefined |
true |
false |
null 和
undefined 仅在 ==
下视为相等(规范定义)。 |
null == null |
true |
true |
自身比较始终相等。 |
undefined == undefined |
true |
true |
自身比较始终相等。 |
NaN == NaN |
false |
false |
NaN
是唯一不等于自身的值。 |
null == NaN |
false |
false |
null
不转换为数字,NaN 与任何非自身值比较均为
false 。 |
undefined == NaN |
false |
false |
undefined 转换为
NaN ,但 NaN 不等于自身外的任何值。 |
NaN == undefined |
false |
false |
同上。 |
NaN == null |
false |
false |
同上。 |
undefined == null |
true |
false |
与第一行一致,重复强调。 |
特别地,任何值、即使是NaN
自身与NaN
进行==
或===
判断,全部会返回false
。判断值是否为NaN
,应使用Number.isNaN(x)
或Object.is(x, NaN)
。
空值合并??
派生自逻辑或||
,是为了应对JavaScript中涉及null
或undefined
但又需要逻辑运算的场景而生。a ?? b
表示若左侧操作数a
为null
或undefined
,则返回右侧操作数b
;否则返回a
。相比之下,||
会将所有Falsy值(如0
、""
、false
、NaN
)视为无效,而??
仅针对null
与undefined
,保留其他Falsy值。
展开运算符...
是ECMAScript
6标准新增的语法糖,用于可迭代对象展开或函数参数收集,例如["天馬咲希", ...["星乃一歌"]]
在内容上["天馬咲希", "星乃一歌"]
是完全相同的,尽管会由于内存地址的不同导致==
与===
判断的结果为false
。
操作符(Operator-like Constructs)
常见的JavaScript操作符有:
- 成员操作符:
.
- 类型操作符:
typeof
(类型检测),instanceof
(原型链检测),in
(属性存在性) - 其他操作符:
,
,()
(分组操作符),void
(返回undefined
),delete
(属性删除),new
流程控制
JavaScript的流程控制语句在基础语法结构上与Java无异,均通过if
/else if
/else
与switch
进行(多)条件判断,通过for
进行计数或遍历循环,通过while
与do while
进行条件循环,通过break
与continue
控制循环中断或跳过迭代。不过,JavaScript的流程控制语句在底层实现与细节上与Java仍然有一些差别且存在一些独有的特性。
if (x)
会隐式调用Boolean(x)
,而在Java中条件表达式必须为布尔类型,非布尔值会导致编译错误。switch (x)
使用全等运算符===
匹配case
值,类型不同视为匹配失败;同时,与Java中switch
相同的是两者均存在穿透行为,要避免这一情况需要为case
添加break
。- JavaScript的循环支持标签语法以实现在多层循环中精确控制循环跳转,此外JavaScript还提供了两种不同的for循环:
for of
与for in
。for of
的基本语法为for (value or arr)
,通常会写为for (const value or arr)
以防止值被修改,用于处理可迭代对象(如字符串、数组与集合)直接获取值,对标Java中的增强for循环for (type value : arr)
。该语法依赖Symbol.iterator
接口,普通对象需手动实现该接口或通过Object.values()
转换。for in
的基本语法为for (key in obj)
,通常会写为for (const key or obj)
以防止值被修改,用于遍历对象的键名且遍历顺序并不固定,需配合hasOwnProperty()
过滤原型链属性。for in
虽然也可以遍历数组,但由于索引是字符串而非数字,建议使用for of
遍历数组。
函数
函数声明
JavaScript函数有如下三种定义方式:
显式函数声明:
1
2
3
4function funcName(arg1, arg2, ......) {
// 执行逻辑
return result; // 如果该函数不需要返回值,省略return即可
}显式声明支持提升特性(Hoisting),声明和函数体均被提升,可以在声明前的代码中调用。
同时,显式声明也是构造函数的标准声明方式,具有
prototype
属性。函数表达式:
1
2
3
4var varName = function funcName(arg1, arg2, ......) { // var也可以按需替换为const
// 执行逻辑
return result; // 如果该函数不需要返回值,省略return即可
}其中
funcName
可以省略,即函数表达式支持定义匿名函数。函数表达式没有提升特性,也就是说变量的声明varName
会提升但函数体不会被提升。函数表达式常被用于回调函数、闭包与动态赋值中。此外,即使没有省略函数名,
funcName
也仅在函数体内部可见。因此在以这种方式定义函数时,如果函数不涉及递归调用,则完全可以省略函数名。箭头函数(ES6+):
JavaScript箭头函数的使用场景对标Java Lambda表达式,完整的基本语法结构为
(arg1, arg2, ......) => { ...... }
,当只有一个参数时也可以简化为arg => expression
,无参数时应保留括号() => expression
,其中简化写法中的expression
等价于完整写法中的{ return expression }
。箭头函数无提升特性。箭头函数具有一些普通函数所没有的特性:
- 无
this
:箭头函数不会创建自己的this
,而是继承自外层作用域(词法作用域) - 没有
arguments
对象:如果需要捕获多余参数,必须使用剩余参数对象 - 不能作为构造函数:没有prototype属性,无法被
new
调用
- 无
函数参数与调用
函数在被调用时,对原始类型按值传递,对象类型按引用传递。
JavaScript函数在调用时可传入任意数量参数,可以用arg = defaultValue
指定参数的默认值,未传递的参数值将被undefined
填充,多余参数默认被忽略,但可通过arguments
对象(箭头函数除外)或在形参最后一个被声明的剩余参数...args
捕获,例如:
1 | function sum(...numbers) { |
不推荐使用arguments
对象,因为arguments
只是类数组对象(拥有length
属性和数字索引,但不具备数组方法),需要使用Array.from()
转换为数组对象,故应优先采用剩余参数。在使用剩余参数时应区分剩余参数形参与展开运算符...
。
在JavaScript中,函数也是一类对象。普通的函数对象拥有prototype
属性与[[Construct]]
,可以通过new
实例化,例如const myFunc = new MyFunc();
,此时this
指向新实例化的对象,但箭头函数没有prototype
属性与[[Construct]]
,无法通过new
调用。
- 对于函数的普通调用
func();
,如果启用严格模式this
指向undefined
,否则在浏览器中指向window
- 对于方法调用
obj.method();
,this
指向调用对象obj
- 对于构造函数调用
new Obj();
,this
指向新创建的实例 - 对于间接调用,视指定对象而定
JavaScript函数可以通过.call()
与.apply()
进行临时的间接调用,使用方法分别为func.call(thisArg, arg1, arg2, ......)
和func.apply(thisArg, [argsArr])
,区别仅仅是逐个传递func
参数与将func
参数通过数组或数组对象整个传递。这两个调用均会立即执行函数,并且this
指向调用中被传入的参数thisArg
。
除了.call()
与.apply()
,JavaScript函数还可以通过.bind()
进行永久的绑定,使用方法为func.bind(thisArg, arg1, arg2, ......)
。.bind()
不会立即执行函数,而是预绑定部分参数,函数在后续被调用时只需要传入剩余参数。然而,.bind()
一旦绑定了thisArg
,this
便永久指向thisArg
,无法被.call()
与.apply()
临时覆盖。
JavaScript还支持在函数的形参中解构,以{}
声明对象解构模式、以[]
声明数组解构模式,例如:
1 | function cast({ oc = "天馬咲希", cv: characterVoice }) { // 解构对象,为oc设定默认值,为cv起别名 |
1 | const movieData = [ |
函数的其他特性
- 闭包:机制与Python闭包相同
- 高阶函数
- IIFE(立即执行函数)
回调函数
回调函数的核心是将函数作为参数传递给另一函数,并由宿主函数在特定时机调用。回调函数本身不一定涉及异步,同步回调仍是顺序执行的、阻塞的,例如数组的forEach
方法,而在异步回调中宿主函数(典型如fetch
、XMLHttpRequest
)会将回调推入事件队列,等待主线程空闲后执行,此时代码执行存在延迟与异步。回调函数是异步编程的基石,其核心价值在于分离请求触发与响应处理。
常用ECMAScript对象
Array对象
Array对象用于定义数组,有两种等价的定义方式:
var arr = new Array(1, 2, 3, 'a', 'b');
var arr = [1, 2, 3, 'a', 'b'];
JavaScript数组长度可变,且不限定内容的数据类型。在为数组赋值时,可以选择对越界索引位置赋值,此时在原有长度以后、赋值位置以前的位置会被默认初始化为undefined
。
常用属性:
.length
:设置或返回数组中元素的数量
常用方法:
.forEach(func)
:遍历数组中的元素,将遍历的元素作为参数传入函数func()
并调用。forEach
在遍历数组时会忽略undefined
,如果希望对undefined
处理,需要改为for
循环。典型用法:
1
2
3
4
5
6
7var vs = ['初音ミク', '鏡音リン', '鏡音レン', '巡音ルカ', 'MEIKO', 'KAITO'];
vs.forEach(function(e) { // 函数表达式
console.log(e);
});
vs.forEach(e => console.log(e)); // 箭头函数,最为常用.push(x)
:将元素插入到数组尾部,并返回新的长度。.splice(start, deleteCount)
:从数组中删除指定位置区间上的元素,后续元素前移填补删除位置。如果希望删除单个索引n
上的数据,可以调用arr.splice(n, 1)
。
String对象
String是JavaScript中的字符串对象,有两种等价的定义方式:
var str = new String("天馬咲希");
var str = '天馬咲希';
String也是可迭代对象,并且也可以通过索引直接访问元素,例如console.log("天馬咲希"[3]);
将提示希
。通过这种方式访问时,如果越界访问,将返回undefined
。
常用属性:
.length
常用方法:
.charAt(index)
:获取指定索引位置上的字符。通过这种方式访问时,如果越界访问,将返回空字符串""
。.indexOf(str)
:确定一个子串在目标字符串中首次出现的起始索引。如果子串未在目标字符串中出现,将返回-1
。.trim()
:返回去除左右两侧连续空格后的字符串。.substring(start, end)
JavaScript自定义对象
JavaScript自定义对象示例:
1 | var objectName = { |
JSON
JSON(JavaScript Object
Notation)是一种轻量级数据交换文本格式,强调跨平台、跨语言的通用性。JSON是JavaScript自定义对象语法的子集,存在若干严格限制,例如键名强制使用双引号包裹、不支持函数和undefined
等非数据类的值,而在JavaScript自定义对象的语法中单引号、无引号均可,也可以定义非数据类型的值。
JSON只允许如下几种值:
- 数字:整数或浮点数
- 字符串:必须包裹于双引号中
- 布尔值:true或false
- 数组:包裹于方括号中
- 对象:包裹于花括号中
- 空值:null
其他说明:
- 如前文所述,JSON要求键名必须被双引号包裹。
- JSON数字使用IEEE-754双精度浮点格式,整数精度为15位,浮点数最多17位小数。
- JSON标准禁止添加注释,需通过外部文档说明数据结构。
- 非JSON允许的数据类型在序列化时将被过滤。
JavaScript提供了JSON对象以及一些有关JSON的操作:
JSON.parse(jsonStr)
:将JSON文本(字符串)解析为JavaScript对象JSON.stringify(jsonObj)
:将JSON对象转换为字符串
常用Web API对象
BOM
BOM(Browser Object Model,浏览器对象模型)将浏览器的各个组件封装为对象,允许JavaScript与浏览器交互。
BOM中最常用的五个对象分别为:
- Window:浏览器窗口对象
- 通过
window
对象获取,其中window.
可以省略,例如alert("Hello Window");
- 常用属性
history
:对History对象的只读引用location
:用于窗口或框架的Location对象navigator
:对Navigator对象的只读引用
- 常用方法
alert(str)
:弹出一个带有一段消息与一个确认按钮的警告框confirm(str)
:弹出一个带有一段消息、确认按钮与取消按钮的对话框,并返回用户的选择(布尔值)setInterval(func, ms)
:定时器,按指定周期调用函数或计算表达式setTimeout(func, ms)
:定时器,在指定毫秒后调用一次函数或计算表达式
- 通过
- Navigator:浏览器对象
- Screen:屏幕对象
- History:历史记录对象
- Location:地址栏对象
- 通过
window.location
或location
获取 - 常用属性
href
:设置或返回完整的URL,若修改herf
则跳转至指定地址
- 通过
DOM
DOM(Document Object Model,文档对象模型)将标记语言的各个组成部分封装为对象,HTML的每个标签都对应一个元素对象
Core DOM是所有文档类型的通用基础抽象模型(如XML、HTML、SVG),定义了六种基础接口:
- Document:文档根节点,包含DOCTYPE、注释等子节点。
- Node:所有DOM节点的基类接口,定义
parentNode
、childNodes
等核心属性。 - Element:元素节点接口,每个标签都对应了一个元素对象。
- Attr(Attribute):属性节点接口。浏览器解析HTML时,标签属性(如
<a href>
)会被映射为元素的属性(Element.attributes),而非独立创建Attr对象。Attr接口主要用于XML DOM的精细化操作,常被XML DOM使用,HTML一般通过element.attrName
或element.getAttribute()
直接访问。 - Text:文本节点接口,每个标签内的文本都对应了一个文本对象,存储元素内的文本内容。
- Comment:注释节点接口,每个注释都对应了一个注释对象。
W3C除了定义Core DOM外,还针对HTML定义了具体的HTML
DOM、针对XML定义了具体的XML DOM。例如,HTML DOM中继承自Core
DOM的Element接口而特有的Image对象(<img>
)与Button对象(<input type="button">
),在XML
DOM中并不存在。
HTML DOM扩展:
- HTMLImageElement(
<img>
)、HTMLInputElement(<input>
)等元素专用接口 - EventTarget:事件处理接口
- HTMLSelectElement等:表单控件扩展
HTML被浏览器加载并解析后会被封装为若干对象,同时在内存中生成DOM树。DOM
树由节点层级关系构成(如父节点、子节点、兄弟节点),可通过parentNode
、childNodes
等属性遍历;文档节点(Document)是树的根节点,包含<html>
、<!DOCTYPE html>
等非元素节点。以下述HTML为例:
1 |
|
对应的DOM树为:
1 | Document |
通过DOM以及JavaScript的事件监听机制,可以控制网页的行为:
- 改变HTML元素的内容
- 改变HTML元素的样式,即改变CSS
- 对HTML DOM事件做出响应
- 添加或删除HTML元素
在浏览器实现中优先通过元素属性直接访问HTML属性(如element.href
),而非操作Attr对象。在JavaScript中,可以通过Document对象获取各个Element对象,Document对象则通过Window对象获取,不过如前文所述,JavaScript代码中window.
可以省略。以下为若干由Document对象提供的一些常用的获取Element对象函数:
根据id属性值获取,返回单个Element对象
1
var h1 = document.getElementById("h1");
根据标签名称获取,返回Element对象数组
1
var a = document.getElementByTagName("a");
根据name属性值获取,返回Element对象数组
1
var students = document.getElementByName("天馬咲希");
根据class属性值获取,返回Element对象数组
1
var schoolStudents = document.getElementByClassName("Miyamasuzaka Girls' Academy");
注:jQuery是一个JavaScript的第三方库,用以简化Web开发,统一了浏览器操作、提高了DOM操作效率。然而,站在2025年jQuery已是过时技术,jQuery的核心功能已经被Vue/React、querySelector/fetch等新技术完全替代,没有必要大费功夫钻研。
获取到Element对象后,就可以在MDN Web Docs - Element查询该对象的属性、方法并进行操作。譬如,对于前文中示例HTML,可以通过如在页面内引入JavaScript内部脚本修改页面:
1 | <script> |
事件与事件监听
HTML事件是指发生在HTML元素上的交互。JavaScript可以在事件被侦测到时执行指定代码,此为事件监听。
JavaScript通过事件绑定进行事件监听。有两种事件绑定方式:
通过HTML标签中的事件属性绑定,糅合了HTML与JavaScript。
1
2
3
4
5
6
7<label><input type="button" onclick="clickon()" value="▶"> Untitled</label>
<script>
function clickon() {
alert("就算再怎么点也不会进入sekai的");
}
</script>通过DOM元素属性绑定:在HTML标签中添加属性
DOMEvent="func()"
,并在JavaScript脚本中实现函数func()
。1
2
3
4
5<label><input type="button" onclick="clickon()" id="sekai" value="▶"> Untitled</label>
<script>
document.getElementById("sekai").onclick = () => alert("虽然不会进入sekai,但这是通过DOM事件绑定的");
</script>
DOM元素提供了一些常见的事件监听方法:
DOM事件 | 桌面键鼠交互设备定义 | 便携触控交互设备定义 |
---|---|---|
onclick |
鼠标点击时触发 | 触摸屏幕时触发,但存在300ms延迟(为区分单击/双击缩放),可通过<meta name="viewport"> 禁用延迟 |
onblur |
元素失去焦点时触发 | 与桌面键鼠交互设备相同 |
onfocus |
元素获得焦点时触发 | 与桌面键鼠交互设备相同 |
onload |
某个页面或图像加载完成时触发 | 与桌面键鼠交互设备相同 |
onsubmit |
表单提交时触发 | 与桌面键鼠交互设备相同 |
onkeydown |
物理键盘按键按下时触发 | 虚拟键盘输入时触发,但中文输入法组合输入阶段不触发(可以通过用oninput 替代触发) |
onmouseover |
光标移动到某元素上时触发 | 默认不触发,可以通过长按手势模拟触发 |
onmouseouot |
光标从某元素上移开时触发 | 默认不触发,可以通过长按手势模拟触发 |
ontouchstart (移动端增强事件) |
默认不触发 | 手指接触屏幕瞬间时触发,包含触点坐标event.touches[0].clientX/Y |
ontouchend (移动端增强事件) |
默认不触发 | 手指离开屏幕瞬间时触发,可用于滑动结束判定 |
ontouchmove (移动端增强事件) |
默认不触发 | 手指在屏幕滑动时触发,可以配合event.preventDefault() 阻止默认滚动 |
orientationchange (移动端增强事件) |
默认不触发 | 设备横竖屏切换时触发,可以配合window.orientation
获取角度 |
异步编程
JavaScript异步编程基本框架:
基础层(AJAX)
AJAX(Asynchronous Javascript And XML)是一种用于数据交换(向服务器发送请求与响应)与异步交互(部分更新网页而非重新加载整个页面)的技术方案,依赖异步通信的原理和原生实现(如
XMLHttpRequest
与Fetch
)。AJAX 的本质是异步通信,需通过回调机制避免页面卡顿;在AJAX中,回调函数通过事件驱动模型实现非阻塞操作(如XMLHttpRequest.onreadystatechange
),允许代码在等待服务器响应时继续执行其他任务。抽象层(Promise)
引入现代JavaScript异步编程的基石——
Promise
解决回调地狱问题,利用状态(pending
/fulfilled
/rejected
)进行流程管理,通过链式调用.then()
/.catch()
扁平化了异步代码结构。语法层(async/await)
async
/await
基于Promise
,进一步用同步的语法大大简化了异步逻辑的代码。
Axios是一个基于Promise的HTTP客户端库,是AJAX的高阶封装。
Vue
Vue是一款用于构建用户界面的开源JavaScript框架,避免了在原生JavaScript中直接对DOM的操作,简化了代码书写。Vue基于MVVM(Model-View-ViewModel)设计哲学,实现数据双向绑定,方便开发者将前端程序设计的关注点放在数据上。更灵活,更简单。截止至2025年,Vue的主流版本是Vue 3,这也是最新的版本,Vue 2已于2023年年底停止维护。
Vue基础
Vue是由尤雨溪创办并维护的项目,中文文档十分全面,请直接移步Vue简体中文官方网站以获得最新最全面的Vue官方文档。
Element UI
HTTP协议与Tomcat
HTTP(Hypertext Transfer Protocol)是一个简单的请求-响应协议(request-response protocol,一次请求对应一次响应),属于应用层协议,通常运行在传输层TCP(TransmissionControl Protocol)之上,不过HTTP/3已改用基于UDP的QUIC协议(以解决队头阻塞问题:若一个TCP连接上的某个数据包丢失,后续所有数据需等待重传,导致整体延迟增加)。HTTP协议中的数据又被称为报文。
HTTP协议还是无状态的,对于事务处理没有记忆能力。HTTP协议的默认端口号为80。
HTTP/1协议规定了GET、POST与HEAD三种方法,HTTP/1.1新增OPTIONS、PUT、DELETE、TRACE与CONNECT五种方法。
方法 | 幂等性 | 语义 | 适用场景 |
---|---|---|---|
GET | 是 | 资源获取 | 数据查询、页面加载 |
POST | 否 | 资源创建/非幂等操作 | 表单提交、API指令执行 |
PUT | 是 | 资源全量更新 | 文档替换(需提供完整资源体) |
DELETE | 是 | 资源删除 | 文件移除、记录删除 |
HEAD | 是 | 获取资源元数据 | 资源预检(验证有效性/检查更新) |
OPTIONS | 是 | 查询支持的方法 | 跨域预检请求(CORS)、服务器功能探测 |
TRACE | 是 | 回显请求报文 | 网络诊断(测试请求路径是否被篡改) |
CONNECT | 是 | 建立隧道连接 | 通过HTTPS代理隧道(SSL/TLS加密通信)与目标服务器建立TCP连接,传输非HTTP协议的内容 |
HTTP请求
所有的HTTP请求都应遵守以下结构,由请求行、请求头与可能的请求体组成:
1 | GET请求 |
如果是HTTP/1.1请求,则不需要也不应出现伪头字段。请求体与请求头之间存在一个空行。
传统请求头中的常见字段:
传统请求头字段 | 说明 |
---|---|
accept | 客户端接收的数据类型 |
accept-encoding | 客户端接收的数据编码格式或压缩格式 |
accept-language | 客户端接收的语言类型。zh-CN 为中国大陆简体中文,en-US 为美式英语,标准格式为语言 + "-" + 地区 |
user-agent | 浏览器信息 |
host | 标服务器的IP(或域名)及端口号,在HTTP/1.1中为强制字段,在HTTP/2中由伪头:authority 替代 |
connection | 服务器处理请求的方式,keep-alive 回传数据后保持一段时间的连接,在HTTP/1.1中默认启用,closed 回传数据后可以立即断开连接。HTTP/2默认采用多路复用技术,已弃用该字段 |
referer | 表示当前请求的来源页面URL,用于防盗链、流量统计等 |
cookie | 携带客户端存储的会话信息(如用户身份凭证),格式为键值对,例如sessionID=arthur-stat; username=asheovo |
content-type | 指定请求体的媒体类型(如application/x-www-form-urlencoded 、multipart/form-data ),为所有携带请求体的请求所必需,GET请求由于在语义上不存在请求体,不需要该请求头字段。其中application/x-www-form-urlencoded 提交的数据格式为URL编码,multipart/form-data 则是将多段数据或文件以流的形式提交给服务器,通过boundary 分隔不同字段,无URL编码,字段值将直接以原始字节传输 |
content-length | 请求体内数据的长度 |
authorization | 传递身份验证凭证(如Bearer Token、Basic
Auth),格式为认证类型 + 凭证 |
cache-control | 控制缓存行为(如no-cache 强制验证新鲜度,max-age=3600 设置缓存有效期) |
HTTP/2中的新增请求伪头字段:
请求伪头字段 | 说明 |
---|---|
:method | 请求方法(GET/POST 等) |
:scheme | 协议类型(http/https) |
:path | 请求路径与查询参数 |
:authority | 用以替代HTTP/1.1中的host 头 |
在HTTP/2中,字段名强制全部小写。以上四个伪头字段在所有的HTTP/2的请求中必须出现,且顺序必须为:method → :scheme → :path → :authority
,这些伪头字段由客户端生成,不可自定义,自定义的非法伪头字段将被视为违规,导致连接中断。
GET请求
GET请求的请求参数在请求行中,请求大小受限。
以下是在访问《世界計畫 繽紛舞台! feat. 初音未來》Facebook官方账号主页时向服务器发送的HTTP/2 GET请求报文(获取账号主页背景图片):
1 | GET /v/t39.30808-6/461564945_847362014255390_8662577603862303230_n.jpg?_nc_cat=106&ccb=1-7&_nc_sid=2285d6&_nc_ohc=ae6KWiWwRFYQ7kNvgGFz6td&_nc_oc=AdmGQkBB32_89_WGm_wcST2ZzsHjp26erXOnvYP4JNdZdmUJlARE4zmeYsBrJBlR9tA&_nc_zt=23&_nc_ht=scontent-nrt1-1.xx&_nc_gid=VxfhLrTmKsQTsR7AZUMD9w&oh=00_AYF-VsXSEfXTCvs_GbghN0IBmMhGigmGGOReiL1UlwXZtw&oe=67E6CB4C HTTP/2.0 |
POST请求
POST请求的请求参数在请求体中,无大小限制。
以下是在重庆大学教务处官网进行搜索时向服务器发送的带有请求体结构的HTTP/2 POST请求报文:
1 | POST /system/dwr/call/plaincall/NewsSearchDWR.isSearch.dwr |
HTTP响应
所有HTTP响应均遵循以下层级结构,由状态行、响应头与可能的响应体组成,协议版本差异由连接层隐式处理(如HTTP/2无需显式声明版本):
1 | HTTP响应 |
状态行是响应的核心元数据,包含协议版本、状态码、状态短语,其中状态短语是人类可读的状态描述,例如OK
、Not Found
。响应体与响应头之间存在一个空行。
常见状态码定义:
类别 | 语义 | 常见状态码与场景 |
---|---|---|
1xx | 信息性响应 | 100 Continue (客户端需继续发送请求体) |
2xx | 成功响应 | 200 OK (标准成功)201 Created (资源已创建)204 No Content (无返回体) |
3xx | 重定向响应 | 301 Moved Permanently (永久重定向,SEO友好)302 Found (资源已移动至Location 响应头中给定的URL,浏览器将重新访问至新页面)304 Not Modified (缓存未失效,自上次请求资源后服务端未修改资源,客户端可直接使用本地缓存数据) |
4xx | 客户端错误 | 400 Bad Request (语法错误)401 Unauthorized (需认证)403 Forbidden (无权限)404 Not Found (未找到资源)405 Method Not Allowed (方法不允许,例如某资源必须通过GET获取却使用了POST)428 Precondition Eequired (有条件请求,客户端访问资源必须携带特定请求头)429 Too Many Requires (客户端在给定时间内发送过多请求,在响应头retry-after 字段中可告知客户端多久以后可再请求)431 Request Header Fileds Too Large (请求头过大,服务端不予处理) |
5xx | 服务器错误 | 500 Internal Server Error (代码异常,服务器发生不可预期的错误)503 Service Unavailable (服务器过载或尚未初始化) |
响应头中的常见头字段:
响应头字段 | 作用与示例 |
---|---|
content-type | 响应体MIME类型,如text/html; charset=utf-8 、application/json 、image/jpeg 、application/octet-stream (文件下载) |
content-length | 响应体字节数,如Content-Length: 1024 (对分块传输无效) |
content-encoding | 声明响应体压缩方式,如gzip (GZIP压缩)、br (Brotli) |
cache-control | (客户端)资源缓存策略,如max-age=3600 (缓存1小时)或no-store (禁止缓存) |
location | 重定向目标URL,如Location: /new-page (需配合3xx状态码) |
set-cookie | 设置会话凭证,如Set-Cookie: sessionId=abc123; Path=/ |
server | 服务器软件信息,如Server: Apache/2.4.6 |
GET响应
以下是访问《世界計畫 繽紛舞台! feat. 初音未來》Facebook官方账号主页时服务器返回的HTTP/2 GET响应报文:
1 | 304 Not Modified |
POST响应
以下是在重庆大学教务处官网进行搜索后服务器返回的带有响应体结构的HTTP/2 POST响应报文:
1 | 200 OK |
Tomcat
Tomcat是Apache软件基金会开发的开源Java Servlet容器和轻量级Web服务器,实现了Java Servlet、JSP(JavaServer Pages)等规范,为动态Web应用提供运行环境。通过对HTTP协议操作进行了封装,简化了Web程序开发。
Spring
Boot内嵌了Tomcat服务器,位于起步依赖spring-boot-starter-web
中(依赖传递),在开发与测试阶段不需要自行安装、启动。在部署阶段,仍需要自行配置Tomcat。