JavaScript | 爬虫逆向 | 语法基础| 01
一、摘要

实践是最好的导师
二、环境配置
在开始之前,需要确保你的计算机上已经安装了 Node.js。Node.js 是一个开源的、跨平台的 JavaScript 运行时环境,它允许你在服务器端运行 JavaScript 代码。
1. 下载
安装地址:https://nodejs.org/zh-cn/download
安装稳定版本,选择windows 64位:
根据你的操作系统(Windows、macOS 或 Linux),选择对应的安装包。
例如,如果你使用的是 Windows 系统,点击 “Windows Installer” 按钮下载 .msi 安装程序。
下载完成后,运行安装程序。在安装过程中,你可以选择默认的安装路径,也可以自定义路径。
安装程序会自动安装 Node.js 和 npm(Node.js 的包管理工具)。

下载好进行一直下一步即可
2. 配置环境
2.1 配置系统环境
为你刚刚安装node环境的位置

验证是否成功

2.2 pycharm环境变量

配置 Node.js 解释器,为前面安装node的路径

验证环境,新建一个脚本运行即可

2.3 浏览器安装
chorme浏览器
https://google.cn/intl/zh-CN_ALL/chrome/fallback/
三、JavaScript组成部分

JavaScript 由 ECMAScript(核心语法)、DOM(文档对象模型)、BOM(浏览器对象模型)、JavaScript 引擎、运行时环境以及庞大的生态系统组成。这些部分共同构成了完整的 JavaScript 语言体系,使其能够满足从简单的网页交互到复杂的服务器端应用程序开发的各种需求。
JavaScript 是一种功能强大的编程语言,广泛应用于 Web 开发以及其他领域。它由以下几个主要部分组成,这些部分共同构成了完整的 JavaScript 语言体系。
1.ECMAScript(核心语法)
ECMAScript 是 JavaScript 的核心规范,定义了语言的基本语法、数据类型、操作符、控制结构、函数、对象等基础特性。它是 JavaScript 的“核心”,为 JavaScript 提供了运行的基础。
1.1 数据类型
JavaScript 中有以下几种数据类型:
-
基本数据类型:
String(字符串):用于表示文本数据,例如"Hello, World!"。Number(数字):用于表示数值,例如42或3.14。Boolean(布尔值):用于表示逻辑值,只有两个值:true和false。Undefined(未定义):表示变量已声明但未初始化,例如let x;。Null(空值):表示“无”,是一个特殊的值,例如let y = null;。Symbol(ES6 新增):表示一个唯一的、不可变的数据类型,常用于对象属性的键。BigInt(ES2020 新增):用于表示大于2^53 - 1的整数。
-
复杂数据类型:
Object(对象):用于表示一组键值对的集合,例如{ name: "John", age: 25 }。Array(数组):用于表示一组有序的值的集合,例如[1, 2, 3, 4, 5]。Function(函数):用于封装可重复使用的代码块,例如function add(a, b) { return a + b; }。
1.2 控制结构
JavaScript 提供了多种控制结构,用于控制程序的执行流程:
- 条件语句:
if (condition) {// 如果条件为真,执行这里的代码 } else if (anotherCondition) {// 如果另一个条件为真,执行这里的代码 } else {// 如果所有条件都不满足,执行这里的代码 } - 循环语句:
// for 循环 for (let i = 0; i < 5; i++) {console.log(i); }// while 循环 let i = 0; while (i < 5) {console.log(i);i++; }// do-while 循环 let j = 0; do {console.log(j);j++; } while (j < 5);
1.3 函数
函数是 JavaScript 中的基本构建块,用于封装可重复使用的代码块。JavaScript 中的函数是一等公民,可以作为变量赋值、作为参数传递或作为返回值。
function add(a, b) {return a + b;
}const result = add(3, 4); // 调用函数
console.log(result); // 输出 7
1.4 模块(ES6 引入)
模块用于组织和管理代码,避免命名冲突,提高代码的可维护性。
// myModule.js
export function sayHello(name) {return `Hello, ${name}!`;
}// main.js
import { sayHello } from "./myModule.js";
console.log(sayHello("John")); // 输出 Hello, John!
2. DOM(文档对象模型)
DOM 是一个与平台和语言无关的接口,用于表示和操作 HTML 或 XML 文档。它将文档表示为一个树形结构,其中每个节点代表文档的一部分(如元素、属性或文本)。
2.1 DOM 树结构
HTML 文档被解析为一个 DOM 树,树的根节点是 document 对象。例如,对于以下 HTML 文档:
<!DOCTYPE html>
<html><head><title>My Page</title></head><body><h1>Hello, World!</h1><p>This is a paragraph.</p></body>
</html>
其 DOM 树结构如下:
document|+-- html|+-- head| || +-- title| || +-- "My Page"|+-- body|+-- h1| || +-- "Hello, World!"|+-- p|+-- "This is a paragraph."
2.2 DOM 操作
通过 JavaScript,可以操作 DOM 树,实现动态更新网页内容、修改样式、添加或删除元素等功能。
// 获取元素
const heading = document.querySelector("h1");
console.log(heading.textContent); // 输出 Hello, World!// 修改元素内容
heading.textContent = "New Heading";// 修改样式
heading.style.color = "red";// 添加新元素
const newParagraph = document.createElement("p");
newParagraph.textContent = "This is a new paragraph.";
document.body.appendChild(newParagraph);// 删除元素
const oldParagraph = document.querySelector("p");
document.body.removeChild(oldParagraph);
3. BOM(浏览器对象模型)
BOM 是浏览器对象模型,它提供了与浏览器窗口相关的对象和接口,用于操作浏览器窗口、管理浏览器历史记录、与浏览器插件交互等。
下面举例一下对象,后续会有在爬虫中举例别的
3.1 window 对象
window 对象是 BOM 的核心,代表浏览器窗口。它是 JavaScript 的全局对象,所有未明确指定作用域的变量和函数都属于 window 对象。
// 打开新窗口
const newWindow = window.open("https://example.com", "_blank");// 关闭窗口
// newWindow.close();// 获取窗口大小
console.log(window.innerWidth); // 获取窗口的内部宽度
console.log(window.innerHeight); // 获取窗口的内部高度// 监听窗口事件
window.addEventListener("resize", () => {console.log("Window resized!");
});
3.2 location 对象
location 对象提供了与当前窗口的 URL 相关的信息,可以用于获取和修改当前页面的地址。
console.log(window.location.href); // 获取当前页面的完整 URL
console.log(window.location.pathname); // 获取当前页面的路径部分// 跳转到新页面
window.location.href = "https://example.com";// 重新加载页面
window.location.reload();
3.3 navigator 对象
navigator 对象提供了有关浏览器的信息,例如浏览器的名称、版本、用户代理字符串等。
console.log(window.navigator.userAgent); // 获取用户代理字符串
console.log(window.navigator.language); // 获取浏览器的语言
3.4 history 对象
history 对象提供了对浏览器历史记录的访问,可以用于导航历史记录。
// 后退到上一个页面
window.history.back();// 前进到下一个页面
window.history.forward();// 添加历史记录条目(HTML5 新增)
window.history.pushState({ state: "newState" }, "New Title", "/new-url");
四、JavaScript语言基础
本章节目录较多 以 【】来强调为目录
官方文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Introduction

建议有时间每天都阅读一下,本章节为爬虫必要掌握内容
1.【注释】
单行注释
var a = 1; // 单行注释
多行注释
console.log("你好")
/*
var a = 1;
var a = 1;
var a = 1;
*/
2. 【语句】
var a = 1 //
var b = 2; //
加分号有助于避免代码省略造成错误,以及压缩代码,提升性能的作用
3. 【关键字与保留字】
在 JavaScript 中,关键字和保留字是两种特殊的词汇,它们在语法解析和代码执行中具有特殊的意义。
所以在写JavaScript代码中,定义变量的时候不要用以下内容
3.1 关键字
| 关键字 | 用途描述 |
|---|---|
break | 用于终止循环或 switch 语句 |
case | 用于 switch 语句中匹配值 |
catch | 用于异常处理中的捕获块 |
class | 用于定义类 |
const | 用于声明常量 |
continue | 用于跳过当前循环的迭代 |
debugger | 用于调试代码 |
default | 用于 switch 语句中的默认分支 |
delete | 用于删除对象的属性 |
do | 用于 do...while 循环的开始 |
else | 用于 if 语句的分支条件 |
export | 用于模块化导出变量、函数或类 |
extends | 用于类继承 |
finally | 用于异常处理中的最终执行块 |
for | 用于循环语句 |
function | 用于声明函数 |
if | 用于条件语句 |
import | 用于模块化导入变量、函数或类 |
in | 用于 for...in 循环中检查对象的属性 |
instanceof | 用于检查对象是否为某个类的实例 |
new | 用于创建对象实例 |
return | 用于从函数返回值 |
super | 用于调用父类的构造函数或方法 |
switch | 用于多分支条件语句 |
this | 用于指向当前对象实例 |
throw | 用于抛出异常 |
try | 用于异常处理中的尝试块 |
typeof | 用于获取变量的类型 |
var | 用于声明变量 |
void | 用于返回 undefined,常用于清除链接的 href 值 |
while | 用于循环语句 |
with | 用于扩展作用域链(不推荐使用) |
3.2 保留字
| 保留字 | 用途描述 |
|---|---|
enum | 未来可能用于枚举类型(目前未使用) |
await | 用于异步函数中暂停执行(在模块或严格模式下是关键字) |
implements | 未来可能用于接口实现(目前未使用) |
interface | 未来可能用于接口定义(目前未使用) |
let | 用于声明块级作用域变量 |
package | 未来可能用于包管理(目前未使用) |
private | 用于类中的私有成员(ES2022 引入) |
protected | 用于类中的受保护成员(ES2022 引入) |
public | 用于类中的公有成员(ES2022 引入) |
static | 用于定义静态方法或属性 |
yield | 用于生成器函数中暂停和恢复执行 |
3.3 区分关键字和保留字的原因
- 语法解析的需要
- 关键字:关键字是 JavaScript 语言的核心组成部分,它们在语法解析中具有明确的语义和功能。例如,
if用于条件语句,for用于循环语句。如果允许开发者将这些关键字用作变量名或函数名,解析器将无法正确区分它们的用途,导致语法错误。 - 保留字:保留字是语言设计者预留的词汇,未来可能会赋予它们特定的功能。例如,
enum是一个保留字,虽然目前没有使用,但语言设计者可能在未来版本中引入枚举类型。保留这些词汇可以避免未来版本中引入新功能时与现有代码冲突。
- 关键字:关键字是 JavaScript 语言的核心组成部分,它们在语法解析中具有明确的语义和功能。例如,
- 代码可读性和一致性
- 使用关键字和保留字作为变量名或函数名会导致代码可读性降低。例如,将
for用作变量名,会让其他开发者难以理解代码的意图。通过区分关键字和保留字,可以确保代码的清晰性和一致性。
- 使用关键字和保留字作为变量名或函数名会导致代码可读性降低。例如,将
- 避免歧义
- 关键字和保留字在语法解析中具有明确的语义,如果允许它们用作普通标识符,可能会导致解析器的歧义。例如,
class是一个关键字,用于定义类。如果允许将class用作变量名,解析器在遇到class时将无法确定它是用于定义类还是作为变量名,从而导致语法错误。
- 关键字和保留字在语法解析中具有明确的语义,如果允许它们用作普通标识符,可能会导致解析器的歧义。例如,
- 语言设计的灵活性
- 保留字为语言的未来发展提供了灵活性。语言设计者可以在未来的版本中引入新的功能,而不用担心与现有代码冲突。例如,ES2015 引入了
let和const作为关键字,用于声明块级作用域变量。如果这些词汇在早期版本中被用作普通标识符,那么引入新功能时就会面临兼容性问题。
- 保留字为语言的未来发展提供了灵活性。语言设计者可以在未来的版本中引入新的功能,而不用担心与现有代码冲突。例如,ES2015 引入了
4. 【变量声明与作用域】
| 声明方式 | 作用域 | 特性 |
|---|---|---|
var | 函数作用域 | 存在变量提升,可重复声明 |
let | 块级作用域 | 无变量提升,不可重复声明 |
const | 块级作用域 | 无变量提升,声明后不可修改 |
var、let 和 const 是 JavaScript 中用于声明变量的三种方式,它们在作用域、提升行为、可变性等方面存在显著区别。以下是它们的详细对比:
var:具有函数作用域或全局作用域,存在变量提升和全局污染问题,尽量少用。let:具有块级作用域,不存在变量提升,可以重新赋值,适用于需要重新赋值的变量。const:具有块级作用域,不存在变量提升,不能重新赋值,适用于常量或不需要重新赋值的变量。
4.1. 作用域
| 特性 | var | let | const |
|---|---|---|---|
| 全局作用域 | 声明的变量属于全局对象(window 或 global),在全局范围内可访问。 | 声明的变量仅在块级作用域内有效(如 {} 内)。 | 声明的变量仅在块级作用域内有效(如 {} 内)。 |
| 函数作用域 | 在函数内声明的变量仅在该函数内有效。 | 在函数内声明的变量仅在该函数内有效。 | 在函数内声明的变量仅在该函数内有效。 |
| 块级作用域 | 无块级作用域,变量会提升到最近的函数或全局作用域。 | 支持块级作用域,变量仅在 {} 内有效。 | 支持块级作用域,变量仅在 {} 内有效。 |
示例:
if (true) {var a = 1;let b = 2;const c = 3;
}
console.log(a); // 1,因为 var 被提升到全局作用域
console.log(b); // ReferenceError,b 仅在块级作用域内有效
console.log(c); // ReferenceError,c 仅在块级作用域内有效
4.2. 变量提升(Hoisting)
| 特性 | var | let | const |
|---|---|---|---|
| 变量提升 | 声明和初始化都会被提升到函数或全局作用域的顶部。 | 声明会被提升,但初始化不会。在声明之前访问会报 ReferenceError。 | 声明会被提升,但初始化不会。在声明之前访问会报 ReferenceError。 |
| 临时死区(TDZ) | 无临时死区,变量会被初始化为 undefined。 | 有临时死区,从块的开始到变量声明之前,变量不可访问。 | 有临时死区,从块的开始到变量声明之前,变量不可访问。 |
示例:
console.log(x); // undefined,var 被提升并初始化为 undefined
console.log(y); // ReferenceError,let 声明之前不可访问
console.log(z); // ReferenceError,const 声明之前不可访问var x = 10;
let y = 20;
const z = 30;
4.3. 可变性
| 特性 | var | let | const |
|---|---|---|---|
| 可变性 | 声明的变量可以重新赋值。 | 声明的变量可以重新赋值。 | 声明的变量不能重新赋值,但对象或数组的属性或元素可以修改。 |
| 重复声明 | 在同一个作用域内可以重复声明同一个变量。 | 在同一个作用域内不能重复声明同一个变量。 | 在同一个作用域内不能重复声明同一个变量。 |
示例:
var a = 10;
var a = 20; // 合法,重复声明不会报错
console.log(a); // 20let b = 10;
let b = 20; // SyntaxError,不能重复声明
console.log(b);const c = 10;
c = 20; // TypeError,不能重新赋值
console.log(c);const obj = { x: 1 };
obj.x = 2; // 合法,对象的属性可以修改
console.log(obj); // { x: 2 }
5. 【数据类型】
在 JavaScript 中,数据类型分为原始数据类型和引用数据类型。引用数据类型是 JavaScript 中非常重要的概念,理解它对于编写高效的爬虫代码、处理动态数据以及应对反爬虫机制至关重要。
-
原始数据类型:直接存储在栈内存中,变量保存的是实际的值。
-
引用数据类型:实际数据存储在堆内存中,变量保存的是堆内存的地址(引用)。
扩展阅读
- MDN 数据类型文档
- JavaScript 类型转换详解
5.1. 原始类型(Primitive Types)
| 数据类型 | 描述 | 示例 | 常见方法 |
|---|---|---|---|
Number | 数值类型,包括整数和浮点数 | 42, 3.14 | toFixed(), toString() |
String | 字符串类型 | "Hello", 'World' | charAt(), toUpperCase(), split() |
Boolean | 布尔类型,true 或 false | true, false | Boolean(value) |
Null | 表示空值 | null | - |
Undefined | 表示未定义的值 | undefined | - |
Symbol | 唯一且不可变的值(ES6引入) | Symbol('desc') | - |
5.1.1. String(字符串)
- 常用方法:
length:获取字符串的长度。const str = "Hello, World!"; console.log(str.length); // 输出 13charAt(index):获取指定索引位置的字符。console.log(str.charAt(7)); // 输出 "W"toUpperCase()和toLowerCase():将字符串转换为大写或小写。console.log(str.toUpperCase()); // 输出 "HELLO, WORLD!" console.log(str.toLowerCase()); // 输出 "hello, world!"includes(searchString, position):检查字符串是否包含指定子字符串。console.log(str.includes("World")); // 输出 true console.log(str.includes("world")); // 输出 falsereplace(searchValue, replaceValue):替换字符串中的内容。console.log(str.replace("World", "JavaScript")); // 输出 "Hello, JavaScript!"split(separator, limit):将字符串分割成数组。console.log(str.split(", ")); // 输出 ["Hello", "World!"]
5.1.2. Number(数字)
- 常用方法:
toFixed(digits):将数字格式化为指定小数位数的字符串。const num = 123.456; console.log(num.toFixed(2)); // 输出 "123.46"toString():将数字转换为字符串。console.log(num.toString()); // 输出 "123.456"toPrecision(digits):将数字格式化为指定精度的字符串。console.log(num.toPrecision(3)); // 输出 "1.23e+2"Math.floor()、Math.ceil()、Math.round():分别用于向下取整、向上取整和四舍五入。console.log(Math.floor(num)); // 输出 123 console.log(Math.ceil(num)); // 输出 124 console.log(Math.round(num)); // 输出 123
5.1.3. Boolean(布尔值)
- 常用方法:
Boolean(value):将值转换为布尔类型。console.log(Boolean("")); // 输出 false console.log(Boolean("Hello")); // 输出 true console.log(Boolean(0)); // 输出 false console.log(Boolean(42)); // 输出 true
5.1.4. Undefined
- 特点:
- 表示变量已声明但未初始化。
- 常用于检查变量是否未赋值。
let x; console.log(x === undefined); // 输出 true
5.1.5. Null
- 特点:
- 表示故意赋予变量的空值。
- 常用于表示“无值”。
let y = null; console.log(y === null); // 输出 true
5.1.6. Symbol(符号)
- 特点:
- 表示一个唯一的、不可变的数据类型,常用于对象属性的键。
Symbol(description):创建一个新的 Symbol。const mySymbol = Symbol("mySymbol"); console.log(mySymbol); // 输出 Symbol(mySymbol)
5.2. 引用类型(Reference Types)
| 数据类型 | 描述 | 示例 | 常见方法 |
|---|---|---|---|
Object | 键值对集合 | { name: "Alice", age: 25 } | Object.keys(), Object.values(), Object.assign() |
Array | 有序的元素集合 | [1, "two", true] | push(), pop(), map(), filter() |
Function | 可执行的代码块 | function greet() { console.log("Hello!"); } | call(), apply(), bind() |
Date | 表示日期和时间 | new Date() | getFullYear(), getMonth(), setFullYear() |
RegExp | 正则表达式,用于字符串匹配 | /pattern/ | test(), exec() |
Map | 键值对集合,键可以是任意类型 | new Map([[1, "one"], [2, "two"]]) | set(), get(), has(), delete() |
Set | 唯一值的集合 | new Set([1, 2, 3]) | add(), has(), delete() |
5.2.1. Object(对象)
- 常用方法:
- 这个将会是重点,原型链时候会详细讲,也可以看我另外一篇没有重构的文章 https://blog.csdn.net/weixin_44238683/article/details/118503753
Object.keys(obj):获取对象的所有键。const obj = { a: 1, b: 2, c: 3 }; console.log(Object.keys(obj)); // 输出 ["a", "b", "c"]Object.values(obj):获取对象的所有值。console.log(Object.values(obj)); // 输出 [1, 2, 3]Object.entries(obj):获取对象的所有键值对。console.log(Object.entries(obj)); // 输出 [["a", 1], ["b", 2], ["c", 3]]Object.assign(target, ...sources):将多个源对象的属性复制到目标对象。const target = { a: 1 }; const source = { b: 2, c: 3 }; console.log(Object.assign(target, source)); // 输出 { a: 1, b: 2, c: 3 }
5.2.2. Array(数组)
- 常用方法:
push(element):向数组末尾添加元素。const arr = [1, 2, 3]; arr.push(4); console.log(arr); // 输出 [1, 2, 3, 4]pop():从数组末尾移除元素。arr.pop(); console.log(arr); // 输出 [1, 2, 3]shift():从数组开头移除元素。arr.shift(); console.log(arr); // 输出 [2, 3]unshift(element):向数组开头添加元素。arr.unshift(1); console.log(arr); // 输出 [1, 2, 3]slice(start, end):从数组中提取部分元素。console.log(arr.slice(1, 3)); // 输出 [2, 3]map(callback):对数组中的每个元素执行回调函数,并返回新数组。const doubled = arr.map((num) => num * 2); console.log(doubled); // 输出 [2, 4, 6]filter(callback):过滤数组中的元素,返回符合条件的元素组成的新数组。const filtered = arr.filter((num) => num > 2); console.log(filtered); // 输出 [3]reduce(callback, initialValue):对数组中的元素进行累积操作。const sum = arr.reduce((acc, num) => acc + num, 0); console.log(sum); // 输出 6
5.2.3. Function(函数)
- 常用方法:
call(context, ...args):调用函数,并指定上下文。function greet() {console.log(`Hello, ${this.name}!`); } greet.call({ name: "Alice" }); // 输出 "Hello, Alice!"apply(context, argsArray):调用函数,并指定上下文和参数数组。greet.apply({ name: "Bob" }, []); // 输出 "Hello, Bob!"bind(context):创建一个新函数,并绑定指定的上下文。const greetAlice = greet.bind({ name: "Alice" }); greetAlice(); // 输出 "Hello, Alice!"
5.2.4. Date(日期)
- 常用方法:
new Date():创建一个表示当前日期和时间的日期对象。const now = new Date(); console.log(now); // 输出当前日期和时间getFullYear()、getMonth()、getDate()等:获取日期的各个部分。console.log(now.getFullYear()); // 输出当前年份 console.log(now.getMonth() + 1); // 输出当前月份(从 0 开始) console.log(now.getDate()); // 输出当前日期setFullYear(year, month, date):设置日期。now.setFullYear(2025, 11, 25); console.log(now); // 输出 2025-12-25getTime():获取当前时间戳。const now = new Date(); console.log(now); // 输出当前日期和时间,例如:2024-05-28T12:34:56.789Z console.log(now.getTime()); // 输出当前时间的时间戳,例如:1717000000000
5.2.5. RegExp(正则表达式)
- 常用方法:
test(string):测试字符串是否匹配正则表达式。const regex = /hello/i; console.log(regex.test("Hello, World!")); // 输出 trueexec(string):执行正则表达式匹配,返回匹配结果。const match = regex.exec("Hello")
6 【函数定义与调用】
函数是 JavaScript 中的基本构建块,它是一段可以重复使用的代码,用于执行特定任务。函数可以接受输入参数,并返回一个值。在 JavaScript 中,函数既可以作为独立的实体存在,也可以作为对象的方法被调用。
6.1. 函数的定义
函数的定义方式主要有以下几种:
6.1.1. 函数声明(Function Declaration)
函数声明是通过 function 关键字定义一个函数。这种方式定义的函数会被提升(hoisting),即可以在声明之前调用。
语法:
function functionName(parameters) {// 函数体
}
示例:
function greet(name) {console.log(`Hello, ${name}!`);
}greet("Alice"); // 输出 "Hello, Alice!"
6.1.2. 函数表达式(Function Expression)
函数表达式是将函数赋值给一个变量。这种方式定义的函数不会被提升,因此必须在声明之后调用。
语法:
const functionName = function(parameters) {// 函数体
};
示例:
const greet = function(name) {console.log(`Hello, ${name}!`);
};greet("wenwenc9"); // 输出 "Hello, wenwenc9!"
6.1.3. 箭头函数(Arrow Function)
箭头函数是 ES6 引入的一种更简洁的函数写法。它没有自己的 this 上下文,而是继承自外部作用域。
语法:
const functionName = (parameters) => {// 函数体
};
示例:
const greet = (name) => {console.log(`Hello, ${name}!`);
};greet("Charlie"); // 输出 "Hello, Charlie!"
6.1.4. 方法(Method)
方法是定义在对象上的函数。它可以通过对象调用,并且在方法内部,this 指向该对象。
语法:
const object = {methodName(parameters) {// 函数体}
};
示例:
const user = {name: "Alice",greet() {console.log(`Hello, ${this.name}!`);}
};user.greet(); // 输出 "Hello, Alice!"
6.1.5. 匿名函数(Anonymous Function)
匿名函数是没有名字的函数,通常用于作为参数传递或立即调用。
示例:
const greet = function(name) {console.log(`Hello, ${name}!`);
};greet("David"); // 输出 "Hello, David!"
6.1.6. 立即调用的函数表达式(IIFE)
立即调用的函数表达式是一种在定义后立即执行的函数。它通常用于创建局部作用域,避免变量污染全局作用域。
语法:
(function(parameters) {// 函数体
})(arguments);
示例:
(function(name) {console.log(`Hello, ${name}!`);
})("Eve"); // 输出 "Hello, Eve!"
6.2. 函数的调用
函数的调用是通过函数名后跟一对圆括号 () 来完成的。调用时可以传递参数,并且函数可以返回值。
6.2.1. 普通调用
直接通过函数名调用。
示例:
function add(a, b) {return a + b;
}const result = add(3, 4); // 调用函数并传递参数
console.log(result); // 输出 7
6.2.2. 作为方法调用
通过对象调用方法时,this 指向该对象。
示例:
const user = {name: "Alice",greet() {console.log(`Hello, ${this.name}!`);}
};user.greet(); // 输出 "Hello, Alice!"
6.2.3. 使用 call、apply 和 bind 调用
这些方法可以明确指定函数的上下文(this)。
call(context, ...args):调用函数,并指定上下文和参数。apply(context, argsArray):调用函数,并指定上下文和参数数组。bind(context, ...args):创建一个新函数,并绑定指定的上下文和部分参数。
示例:
function greet(message) {console.log(`${message}, ${this.name}!`);
}const user = { name: "Alice" };greet.call(user, "Hello"); // 输出 "Hello, Alice!"
greet.apply(user, ["Hi"]); // 输出 "Hi, Alice!"const greetAlice = greet.bind(user, "Hey");
greetAlice(); // 输出 "Hey, Alice!"
6.3. 函数的高级用法
6.3.1. 函数作为参数
函数可以作为参数传递给另一个函数。
示例:
function execute(func, value) {return func(value);
}function double(x) {return x * 2;
}const result = execute(double, 5); // 将 double 函数作为参数传递
console.log(result); // 输出 10
6.3.2. 函数作为返回值
函数可以作为另一个函数的返回值。
示例:
function createMultiplier(factor) {return function(number) {return number * factor;};
}const double = createMultiplier(2); // 返回一个函数
const triple = createMultiplier(3); // 返回另一个函数console.log(double(5)); // 输出 10
console.log(triple(5)); // 输出 15
6.3.3. 高阶函数
高阶函数是接受函数作为参数或返回函数的函数。
示例:
function higherOrderFunction(func) {return function(...args) {console.log(`Calling ${func.name} with arguments: ${args}`);return func(...args);};
}const enhancedAdd = higherOrderFunction(add);
console.log(enhancedAdd(3, 4)); // 输出 "Calling add with arguments: 3,4" 和 7
6.5.4. 函数的上下文(this)
在函数中,this 的值取决于函数的调用方式。在非严格模式下,this 默认指向全局对象(浏览器中是 window,Node.js 中是 global)。在严格模式下,this 是 undefined。
示例:
function greet() {console.log(`Hello, ${this.name}!`);
}const user = { name: "Alice" };greet.call(user); // 使用 call 明确指定 this
// 输出 "Hello, Alice!"
6.5. 函数的其他特性
6.5.1. 默认参数
ES6 引入了默认参数,允许在函数声明时为参数指定默认值。
示例:
function greet(name = "Guest") {console.log(`Hello, ${name}!`);
}greet(); // 输出 "Hello, Guest!"
greet("Alice"); // 输出 "Hello, Alice!"
6.5.2. 剩余参数(Rest Parameters)
剩余参数允许将不定数量的参数表示为一个数组。
示例:
function sum(...numbers) {return numbers.reduce((acc, num) => acc + num, 0);
}console.log(sum(1, 2, 3, 4)); // 输出 10
6.5.3. 展开运算符(Spread Operator)
展开运算符可以将数组或对象展开为单独的元素。
示例:
const numbers = [1, 2, 3];
console.log(Math.max(...numbers)); // 输出 3const obj1 = { a: 1 };
const obj2 = { ...obj1, b: 2 };
console.log(obj2); // 输出 { a: 1, b: 2 }
7【语句】
在 JavaScript 中,语句是构成程序的基本单元,用于执行操作或计算。JavaScript 提供了多种语句类型,用于控制程序的流程、执行条件操作、循环执行代码块等。以下是对 JavaScript 中常见语句类型的详细介绍。
7.4.1. 表达式语句(Expression Statements)
表达式语句是最简单的语句类型,它由一个表达式组成,执行后会返回一个值。
- 示例:
let x = 10; // 表达式语句,赋值操作 console.log(x); // 表达式语句,调用函数
7.4.2. 空语句(Empty Statements)
空语句是一个单独的分号,表示一个空的操作,通常用于跳过某些操作。
- 示例:
; // 空语句
7.4.3. 块语句(Block Statements)
块语句由一对大括号 {} 包裹的语句序列组成,用于将多个语句组合在一起。
- 示例:
{let x = 10;console.log(x); }
7.4.4. 条件语句(Conditional Statements)
条件语句用于根据条件执行不同的代码块。
7.4.4.1. if 语句
if 语句用于根据条件执行代码块。
-
语法:
if (condition) {// 执行的代码块 } -
示例:
let x = 10; if (x > 5) {console.log("x is greater than 5"); }
7.4.4.2. if...else 语句
if...else 语句用于根据条件选择执行两个代码块中的一个。
-
语法:
if (condition) {// 条件为真时执行的代码块 } else {// 条件为假时执行的代码块 } -
示例:
let x = 10; if (x > 5) {console.log("x is greater than 5"); } else {console.log("x is less than or equal to 5"); }
7.4.4.3. switch 语句
switch 语句用于根据变量的值选择执行多个代码块中的一个。
-
语法:
switch (expression) {case value1:// 执行的代码块break;case value2:// 执行的代码块break;default:// 默认执行的代码块 } -
示例:
let day = 3; switch (day) {case 1:console.log("Monday");break;case 2:console.log("Tuesday");break;case 3:console.log("Wednesday");break;default:console.log("Unknown day"); }
7.4.5. 循环语句(Loop Statements)
循环语句用于重复执行代码块,直到满足某个条件为止。
7.4.5.1. while 循环
while 循环在条件为真时重复执行代码块。
-
语法:
while (condition) {// 执行的代码块 } -
示例:
let i = 0; while (i < 5) {console.log(i);i++; }
7.4.5.2. do...while 循环
do...while 循环至少执行一次代码块,然后在条件为真时继续执行。
-
语法:
do {// 执行的代码块 } while (condition); -
示例:
let i = 0; do {console.log(i);i++; } while (i < 5);
7.4.5.3. for 循环
for 循环在满足条件时重复执行代码块,通常用于遍历数组或对象。
-
语法:
for (initialization; condition; increment) {// 执行的代码块 } -
示例:
for (let i = 0; i < 5; i++) {console.log(i); }
7.4.5.4. for...in 循环
for...in 循环用于遍历对象的属性。
-
语法:
for (variable in object) {// 执行的代码块 } -
示例:
const obj = { a: 1, b: 2, c: 3 }; for (let key in obj) {console.log(key, obj[key]); }
7.4.5.5. for...of 循环
for...of 循环用于遍历可迭代对象(如数组、字符串等)的值。
-
语法:
for (variable of iterable) {// 执行的代码块 } -
示例:
const arr = [1, 2, 3]; for (let value of arr) {console.log(value); }
7.4.6. 跳转语句(Jump Statements)
跳转语句用于改变程序的执行流程。
7.4.6.1. break 语句
break 语句用于中断循环或 switch 语句。
- 示例:
for (let i = 0; i < 10; i++) {if (i === 5) {break;}console.log(i); }
7.4.6.2. continue 语句
continue 语句用于跳过当前循环的迭代,继续执行下一次迭代。
- 示例:
for (let i = 0; i < 10; i++) {if (i % 2 === 0) {continue;}console.log(i); }
7.4.6.3. return 语句
return 语句用于从函数返回值,并结束函数的执行。
- 示例:
function add(a, b) {return a + b; } console.log(add(3, 4)); // 输出 7
7.4.6.4. throw 和 try...catch 语句
throw 语句用于抛出异常,try...catch 语句用于捕获和处理异常。
-
语法:
try {// 尝试执行的代码块 } catch (error) {// 捕获异常后的处理代码块 } -
示例:
try {throw new Error("Something went wrong"); } catch (error) {console.error(error.message); }
7.4.7. 其他语句
7.4.7.1. with 语句
with 语句用于扩展作用域链,但不推荐使用,因为它可能导致代码难以理解和维护。
-
语法:
with (object) {// 执行的代码块 } -
示例:
const obj = { a: 1, b: 2 }; with (obj) {console.log(a); // 输出 1console.log(b); // 输出 2 }
7.4.7.2. debugger 语句
debugger 语句用于在代码中设置断点,方便调试。
- 示例:
let x = 10; debugger; // 设置断点 console.log(x);
7.4.7.3. label 语句
label 语句用于为语句块
8 运算符
在 JavaScript 中,运算符用于执行各种操作,包括算术运算、比较、逻辑判断等。以下是 JavaScript 中常见的运算符类型及其使用方法。
8.1 算术运算符(Arithmetic Operators)
算术运算符用于执行基本的数学运算。
| 运算符 | 描述 | 示例 | 结果 |
|---|---|---|---|
+ | 加法 | 5 + 3 | 8 |
- | 减法 | 5 - 3 | 2 |
* | 乘法 | 5 * 3 | 15 |
/ | 除法 | 5 / 3 | 1.6666666666666667 |
% | 求余 | 5 % 3 | 2 |
++ | 自增 | let a = 5; a++; | a 变为 6 |
-- | 自减 | let a = 5; a--; | a 变为 4 |
8.2 比较运算符(Comparison Operators)
比较运算符用于比较两个值,并返回一个布尔值(true 或 false)。
| 运算符 | 描述 | 示例 | 结果 |
|---|---|---|---|
== | 等于(值相等) | "2" == 2 | true |
=== | 严格等于(值和类型都相等) | "2" === 2 | false |
!= | 不等于(值不相等) | "2" != 2 | false |
!== | 严格不等于(值或类型不相等) | "2" !== 2 | true |
> | 大于 | 5 > 3 | true |
< | 小于 | 5 < 3 | false |
>= | 大于等于 | 5 >= 3 | true |
<= | 小于等于 | 5 <= 3 | false |
8.3 逻辑运算符(Logical Operators)
逻辑运算符用于执行逻辑判断,并返回一个布尔值。
| 运算符 | 描述 | 示例 | 结果 |
|---|---|---|---|
&& | 逻辑与(AND) | true && false | false |
| ` | ` | 逻辑或(OR) | |
! | 逻辑非(NOT) | !true | false |
8.4 赋值运算符(Assignment Operators)
赋值运算符用于将值赋给变量。
| 运算符 | 描述 | 示例 | 结果 |
|---|---|---|---|
= | 简单赋值 | let a = 5; | a 为 5 |
+= | 加法赋值 | let a = 5; a += 3; | a 变为 8 |
-= | 减法赋值 | let a = 5; a -= 3; | a 变为 2 |
*= | 乘法赋值 | let a = 5; a *= 3; | a 变为 15 |
/= | 除法赋值 | let a = 5; a /= 3; | a 变为 1.6666666666666667 |
%= | 求余赋值 | let a = 5; a %= 3; | a 变为 2 |
8.5 三元运算符(Ternary Operator)
三元运算符是一种简化的 if...else 语句,用于根据条件返回两个值中的一个。
| 运算符 | 描述 | 示例 | 结果 |
|---|---|---|---|
? : | 三元运算符 | let result = condition ? value1 : value2; | 根据 condition 的值返回 value1 或 value2 |
8.6 位运算符(Bitwise Operators)
位运算符用于对数字的二进制表示进行操作。
| 运算符 | 描述 | 示例 | 结果 |
|---|---|---|---|
& | 位与 | 5 & 3 | 1 |
| ` | ` | 位或 | `5 |
^ | 位异或 | 5 ^ 3 | 6 |
~ | 位非 | ~5 | -6 |
<< | 左移 | 5 << 1 | 10 |
>> | 右移 | 5 >> 1 | 2 |
>>> | 无符号右移 | 5 >>> 1 | 2 |
8.7 条件运算符(Conditional Operators)
条件运算符用于根据条件执行不同的操作。
| 运算符 | 描述 | 示例 | 结果 |
|---|---|---|---|
&& | 短路与 | a && b | 如果 a 为真,则返回 b,否则返回 a |
| ` | ` | 短路或 | |
?? | 空值合并运算符 | a ?? b | 如果 a 是 null 或 undefined,则返回 b,否则返回 a |
8.8 其他运算符
还有一些其他运算符,用于特定的操作。
| 运算符 | 描述 | 示例 | 结果 |
|---|---|---|---|
typeof | 返回变量的类型 | typeof 5 | "number" |
delete | 删除对象的属性 | delete obj.property | true 或 false |
in | 检查对象是否有某个属性 | "property" in obj | true 或 false |
示例代码
以下是一些示例代码,展示如何使用这些运算符:
// 算术运算符
let a = 5;
let b = 3;
console.log(a + b); // 8
console.log(a - b); // 2
console.log(a * b); // 15
console.log(a / b); // 1.6666666666666667
console.log(a % b); // 2// 比较运算符
console.log(a == b); // false
console.log(a === b); // false
console.log(a != b); // true
console.log(a !== b); // true
console.log(a > b); // true
console.log(a < b); // false
console.log(a >= b); // true
console.log(a <= b); // false// 逻辑运算符
console.log(true && false); // false
console.log(true || false); // true
console.log(!true); // false// 赋值运算符
let c = 5;
c += 3; // c = 8
c -= 3; // c = 5
c *= 3; // c = 15
c /= 3; // c = 5
c %= 3; // c = 2// 三元运算符
let result = a > b ? "a is greater" : "b is greater";
console.log(result); // "a is greater"// 位运算符
console.log(5 & 3); // 1
console.log(5
相关文章:
JavaScript | 爬虫逆向 | 语法基础| 01
一、摘要 实践是最好的导师 二、环境配置 在开始之前,需要确保你的计算机上已经安装了 Node.js。Node.js 是一个开源的、跨平台的 JavaScript 运行时环境,它允许你在服务器端运行 JavaScript 代码。 1. 下载 安装地址:https://nodejs.org…...
python解决多个矢量点图层合并为一个点图层
1、解决矢量点图层的合并 2、解决多个点图层分别合并为不同图层(一个文件夹下所有点图层合并为一个图层,以下代码为两个文件夹,分别合并为两个总的图层) import geopandas as gpd import os import pandas as pddef merge_shapef…...
VL开源模型实现文本生成图片
一、 基础知识 根据描述生成图片的视觉-语言模型(Vision-Language Models, VL 模型)是近年来多模态生成领域的热点研究方向。这些模型能够根据自然语言描述生成高质量的图像,广泛应用于艺术创作、设计辅助、虚拟场景构建等领域。 1 根据描述…...
字节跳动实习生主导开发强化学习算法,助力大语言模型性能突破
目录 禹棋赢的背景与成就 主要成就 DAPO算法的技术细节 算法优势 禹棋赢的研究历程 关键时间节点 字节跳动的“Top Seed人才计划” 计划特点 小编总结 在大模型时代,经验不再是唯一的衡量标准,好奇心、执行力和对新技术的敏锐洞察力成为推动技术…...
九、JavaScript作用域、预解析
一、JavaScript作用域 1.JavaScript作用域 ①代码名字(变量)在某个范围内起作用和效果 目的是为了提高程序的可靠性更重要的是减少命名冲突 ②js的作用域(es6)之前:全局作用域 局部作用域 ③全局作用域:整…...
前后端+数据库的项目实战:hbu迎新网-较复杂(下)javaweb
目录 十一、实现对内容的富文本编辑(换行、图片颜色等等样式) (1)下载富文本编辑器,引入资源 (2)将原项目的内容部分替换为富文本编辑器 1、替换添加页面 2、替换修改页面(和添…...
Java-模块二-2
整数类型 byte:在 Java 中占用8位(1字节),因此它的取值范围是从 -128 到 127。这是最小的整数类型,适合用于节省空间的情况。 short:这种类型的大小是16位(2字节),允许的…...
Redis、Memcached应用场景对比
环境 Redis官方网站: Redis - The Real-time Data Platform Redis社区版本下载地址:Install Redis | Docs Memcached官方网站:memcached - a distributed memory object caching system Memcached下载地址:memcached - a dis…...
【单片机通信技术应用——学习笔记三】液晶屏显示技术,取模软件的应用
一、液晶显示技术简介 1.RGB信号线 RGB是一种色彩模式,是工业界的一种颜色标准,是通过红(R)、绿(G)、蓝(B)三个颜色通道的变化,以及它们相互之间的叠加来得到各式各样的…...
MySQL颠覆版系列————MySQL新特性(开启数据库的新纪元)上篇
文章目录 前言一、窗口函数(Window Functions)1.1 窗口函数概念1.2 常见的窗口函数 二、公用表表达式(Common Table Expressions, CTEs)2.1 公用表表达式的概念2.2 常见的公用表表达式 三、JSON增强3.1 JSON增强的概念3.2 常见的J…...
MySQL 调优:查询慢除了索引还能因为什么?
文章目录 情况一:连接数过小情况二:Buffer Pool 太小 MySQL 查询慢除了索引还能因为什么?MySQL 查询慢,我们一般也会想到是因为索引,但除了索引还有哪些原因会导致数据库查询变慢呢? 以下以 MySQL 中一条 S…...
Java实习生面试题(2025.3.23 be)
一、v-if与v-show的区别 v-show 和 v-if 都是 Vue 中的条件渲染指令,它们的主要区别在于渲染策略:v-if 会根据条件决定是否编译元素,而 v-show 则始终编译元素,只是通过改变 CSS 的 display 属性来控制显示与隐藏。 二、mybatis-…...
如何在百度搜索上删除与自己名字相关的资料
个人信息的网络足迹如同一张无形的网,将我们与世界的每一个角落紧密相连。然而,当某些与自己名字相关的资料不再希望被公众轻易检索到时,如何在百度搜索中有效“隐身”,成为了一个亟待解决的问题。面对复杂多变的网络环境…...
【C语言】C语言使用随机数srand,rand
C语言使用随机数srand,rand 可直接编译使用: #include <stdio.h> #include <time.h> #include <stdlib.h> #include <unistd.h>/* c语言提供的跟随机数有关的函数:int rand(void);返回值:产生的随机数void srand(unsiqned int seed);参数…...
为容器指定固定IP地址
文章目录 为容器指定固定IP地址可以通过以下步骤实现,适用于Docker环境:**方法一:使用Docker自定义桥接网络****方法二:Docker Compose配置****关键注意事项** 为容器指定固定IP地址可以通过以下步骤实现,适用于Docker…...
kube-score K8S Yaml静态代码分析工具详解
kube-score 是一款专注于 Kubernetes 配置文件的静态代码分析工具,旨在通过自动化检查帮助用户识别资源配置中的潜在问题,并遵循最佳实践以提升集群的安全性、稳定性和性能。以下是其核心功能、使用方法和应用场景的详细解析: 一、核心功能与…...
Spring Boot 整合 Elasticsearch 实践:从入门到上手
引言 Elasticsearch 是一个开源的分布式搜索引擎,广泛用于日志分析、搜索引擎、数据分析等场景。本文将带你通过一步步的教程,在 Spring Boot 项目中整合 Elasticsearch,轻松实现数据存储与查询。 1. 创建 Spring Boot 项目 首先ÿ…...
使用外部事件检测接入 CDH 大数据管理平台告警
CDH 大数据管理平台 CDH(Cloudera Distribution Hadoop)是一个企业级的大数据平台,由 Cloudera 公司提供,它包含了 Apache Hadoop 生态系统中的多种开源组件,并对其进行了优化和集成,以支持大规模数据存储…...
RabbitMQ八股文
RabbitMQ RabbitMQ 核心概念与组件1. RabbitMQ 核心组件及其作用1.1 生产者(Producer)1.2 交换机(Exchange)1.3 队列(Queue)1.4 绑定(Binding)1.5 消费者(Consumer&#…...
MongoDB(五) - Studio 3T 下载与安装教程
文章目录 前言一、Studio 3T 简介二、下载及安装1. 下载2. 安装 三、使用Studio 3T连接MongoDB 前言 本文旨在全面且深入地为你介绍 Studio 3T。从其丰富的功能特性、跨平台使用的便捷性,到详细的下载安装步骤,以及关键的连接 MongoDB 操作,…...
2025高频面试算法总结篇【链表堆栈队列】
文章目录 直接刷题链接直达反转链表环形链表判断一个序列是否为合理的出栈顺序最长有效括号旋转链表复杂链表的复制约瑟夫环问题滑动窗口最大值 直接刷题链接直达 反转链表 206. 反转链表 环形链表 141. 环形链表142. 环形链表 II 判断一个序列是否为合理的出栈顺序 946.…...
Java主流开发框架之请求响应常用注释
1.RestController 标记一个类为 REST 控制器,处理 HTTP 请求并直接返回数据(如 JSON/XML),而不是视图(如 HTML),一般是放在类的上边 RestController public class UserController {GetMapping…...
汽车制造MES
一、整体生产工序 整车的车间主要分为4个部分:冲压、焊装、涂装、总装、整车入库 系统架构 二、车间概括 1.冲压车间 2.焊装车间 3.涂装车间 4.总装车间 1.整车装配的部件都要可追溯、数据实时性要求高、涉及分装与总装的协调、物流配送的协调、质量批处理的协调、…...
LeetCode 2643.一最多的行:模拟(更新答案)
【LetMeFly】2643.一最多的行:模拟(更新答案) 力扣题目链接:https://leetcode.cn/problems/row-with-maximum-ones/ 给你一个大小为 m x n 的二进制矩阵 mat ,请你找出包含最多 1 的行的下标(从 0 开始)以及这一行中…...
固定翼无人机姿态和自稳模式
固定翼无人机的姿态模式(Attitude/Angle Mode)和自稳模式(Stabilize Mode)是两种常见的飞行控制模式,它们在飞控系统介入程度、操作逻辑及适用场景上有显著区别。以下是两者的详细对比及使用指南: …...
K8S中若要挂载其他命名空间中的 Secret
在Kubernetes(k8s)里,若要挂载其他命名空间中的Secret,你可以通过创建一个 Secret 的 ServiceAccount 和 RoleBinding 来实现对其他命名空间 Secret 的访问,接着在 Pod 中挂载这个 Secret。下面是详细的步骤和示例代码…...
关于Unity的CanvasRenderer报错
MissingReferenceException: The object of type ‘CanvasRenderer’ has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object. UnityEngine.UI.GraphicRaycaster.Raycast (UnityEng…...
LangChain组件Tools/Toolkits详解(5)——返回产出artifact
LangChain组件Tools/Toolkits详解(5)——返回产出artifact 本篇摘要14. LangChain组件Tools/Toolkits详解14.5 返回产出artifact14.5.1 定义工具14.5.2 使用ToolCall调用工具14.5.3 与模型一起使用14.5.4 从子例化BaseTool返回参考文献本章目录如下: 《LangChain组件Tools/T…...
信奥赛CSP-J复赛集训(模拟算法专题)(26):P5412 [YNOI2019] 排队
信奥赛CSP-J复赛集训(模拟算法专题)(26):P5412 [YNOI2019] 排队 题目描述 小明所在的班级要举办一场课外活动,在活动开始之前老师告诉小明:“需要把男女生分成两队,并且每一队都要按照身高从矮到高进行排序”。但是由于小明的马虎,没有把老师的安排转达给同学,导致全…...
基于开源模型的微调训练及瘦身打造随身扫描仪方案__用AI把手机变成文字识别小能手
基于开源模型的微调训练及瘦身打造随身扫描仪方案__用AI把手机变成文字识别小能手 一、准备工作:组装你的"数码工具箱" 1. 安装基础工具(Python环境) 操作步骤: 访问Python官网下载安装包安装时务必勾选Add Python to…...
