编程进阶网 编程进阶网
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • README
  • C语言入门精通

  • Cpp入门到精通

  • Java入门精通

  • Go入门到精通

  • JavaScript入门

    • 基础入门

      • README
      • 入门介绍
      • 数据类型
      • 运算符
      • 函数
      • 面向对象
      • 标准库
        • 6.1 复合数据类型
          • 6.1.1 Object
          • 6.1.2 Array
          • 6.1.3 Map
          • 6.1.4 Set
          • 6.1.5 WeakMap和WeakSet
        • 6.2 特殊数据类型
          • 6.2.1 Date
          • 6.2.2 RegExp
          • 6.2.3 Error
        • 6.3 全局对象
          • 6.3.1 Math
          • 6.3.2 JSON
          • 6.3.3 Promise
          • 6.3.4 Proxy
          • 6.3.5 Reflect
        • 6.4 全局函数
          • 6.4.1 eval
          • 6.4.2 isNaN
          • 6.4.3 isFinite
          • 6.4.4 parseInt
          • 6.4.5 encodeURI
          • 6.4.6 encodeURIComponent
        • 6.5 浏览器相关
          • 6.5.1 Window
          • 6.5.2 Document
          • 6.5.3 Navigator
          • 6.5.4 Location
          • 6.5.5 History
          • 6.5.6 Storage
          • 6.5.7 Fetch
          • 6.5.8 WebSocket
        • 6.6 国际化与本地化
          • 6.6.1 Intl
          • 6.6.2 toLocaleString
        • 6.7 二进制与文件
          • 6.7.1 ArrayBuffer
          • 6.7.2 Blob
          • 6.7.3 File
          • 6.7.4 FileReader
      • 异步操作
      • 事件设计
      • 错误机制
      • 模块开发
      • 字符串处理
      • 迭代器与生成器
      • Symbol
      • DOM操作
      • 网络请求
    • 综合案例

    • 专栏博客

  • CodeX
  • JavaScript入门
  • 基础入门
杨充
2025-11-27
目录

标准库

# 标准库

# 目录介绍

  • 6.1 复合数据类型
    • 6.1.1 Object
    • 6.1.2 Array
    • 6.1.3 Map
    • 6.1.4 Set
    • 6.1.5 WeakMap和WeakSet
  • 6.2 特殊数据类型
    • 6.2.1 Date
    • 6.2.2 RegExp
    • 6.2.3 Error
  • 6.3 全局对象
    • 6.3.1 Math
    • 6.3.2 JSON
    • 6.3.3 Promise
    • 6.3.4 Proxy
    • 6.3.5 Reflect
  • 6.4 全局函数
    • 6.4.1 eval
    • 6.4.2 isNaN
    • 6.4.3 isFinite
    • 6.4.4 parseInt
    • 6.4.5 encodeURI
    • 6.4.6 encodeURIComponent
  • 6.5 浏览器相关
    • 6.5.1 Window
    • 6.5.2 Document
    • 6.5.3 Navigator
    • 6.5.4 Location
    • 6.5.5 History
    • 6.5.6 Storage
    • 6.5.7 Fetch
    • 6.5.8 WebSocket
  • 6.6 国际化与本地化
    • 6.6.1 Intl
    • 6.6.2 toLocaleString
  • 6.7 二进制与文件
    • 6.7.1 ArrayBuffer
    • 6.7.2 Blob
    • 6.7.3 File
    • 6.7.4 FileReader

# 6.1 复合数据类型

# 6.1.1 Object

Object:JavaScript 中最基础的复合数据类型,用于存储键值对集合。

Object 的底层存储原理:V8 引擎对 Object 属性有两种存储策略。命名属性(Named Properties)存储在对象的属性存储区中,通过隐藏类(Hidden Class)定义结构;索引属性(Indexed Properties,如数字键)存储在元素存储区中,类似数组。当属性过多或动态增删频繁时,V8 会将属性存储从快速模式(线性存储)降级为字典模式(哈希表存储)。

常用静态方法:

const person = { name: "Alice", age: 25, city: "Beijing" };

// Object.keys():返回自身可枚举属性名数组
console.log(Object.keys(person)); // ["name", "age", "city"]

// Object.values():返回自身可枚举属性值数组
console.log(Object.values(person)); // ["Alice", 25, "Beijing"]

// Object.entries():返回 [key, value] 对数组
console.log(Object.entries(person));
// [["name", "Alice"], ["age", 25], ["city", "Beijing"]]

// Object.assign():浅拷贝合并对象
const defaults = { theme: "light", lang: "en" };
const userPrefs = { theme: "dark" };
const config = Object.assign({}, defaults, userPrefs);
console.log(config); // { theme: "dark", lang: "en" }

// Object.freeze():冻结对象,不可修改
const frozen = Object.freeze({ x: 1, y: 2 });
frozen.x = 100; // 静默失败(严格模式下报错)
console.log(frozen.x); // 1

// Object.fromEntries():从键值对数组创建对象(ES2019)
const map = new Map([["name", "Bob"], ["age", 30]]);
const obj = Object.fromEntries(map);
console.log(obj); // { name: "Bob", age: 30 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

属性描述符:

const obj = {};
Object.defineProperty(obj, 'name', {
  value: 'Alice',
  writable: false,      // 不可修改
  enumerable: true,     // 可枚举
  configurable: false   // 不可删除/重新配置
});

obj.name = 'Bob'; // 静默失败
console.log(obj.name); // "Alice"
1
2
3
4
5
6
7
8
9
10

# 6.1.2 Array

Array:创建和操作有序集合。

Array 的底层原理:V8 引擎中的数组并非简单的连续内存。当数组元素类型一致(如全是整数)时,V8 使用快速模式(Fast Elements),以 C++ 数组方式存储,访问效率接近 O(1);当数组包含不同类型元素、存在空洞(hole)或非常稀疏时,V8 切换为字典模式(Dictionary Elements),以哈希表存储,节省空间但访问变慢。

常用方法详解:

const arr = [1, 2, 3, 4, 5];

// ========= 变异方法(修改原数组)=========
arr.push(6);           // 末尾添加,返回新长度 → [1,2,3,4,5,6]
arr.pop();             // 末尾删除,返回被删元素 → [1,2,3,4,5]
arr.unshift(0);        // 开头添加 → [0,1,2,3,4,5]
arr.shift();           // 开头删除 → [1,2,3,4,5]
arr.splice(2, 1, 99);  // 从索引2删除1个,插入99 → [1,2,99,4,5]
arr.sort((a, b) => a - b); // 原地排序
arr.reverse();         // 原地反转

// ========= 非变异方法(返回新数组)=========
const nums = [1, 2, 3, 4, 5];

// map:映射转换
const doubled = nums.map(n => n * 2); // [2, 4, 6, 8, 10]

// filter:过滤
const evens = nums.filter(n => n % 2 === 0); // [2, 4]

// reduce:归约
const sum = nums.reduce((acc, n) => acc + n, 0); // 15

// find / findIndex:查找
const found = nums.find(n => n > 3);       // 4
const index = nums.findIndex(n => n > 3);   // 3

// flat / flatMap(ES2019)
const nested = [1, [2, 3], [4, [5]]];
nested.flat();    // [1, 2, 3, 4, [5]]
nested.flat(2);   // [1, 2, 3, 4, 5](指定深度)
nested.flat(Infinity); // [1, 2, 3, 4, 5]

// Array.from:从可迭代对象创建数组
Array.from('hello');       // ['h', 'e', 'l', 'l', 'o']
Array.from({length: 5}, (_, i) => i); // [0, 1, 2, 3, 4]

// at()(ES2022):支持负索引
[1, 2, 3].at(-1);  // 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

时间复杂度总结:

方法 时间复杂度 说明
push/pop O(1) 末尾操作
shift/unshift O(n) 需移动元素
splice O(n) 需移动元素
indexOf/find O(n) 线性查找
sort O(n log n) TimSort 算法
map/filter/reduce O(n) 遍历所有元素

# 6.1.3 Map

Map:存储键值对的集合,键可以是任意类型(包括对象、函数、NaN)。

Map 与 Object 的核心区别:

const map = new Map();

// 任意类型的键
map.set('string', 'value1');
map.set(42, 'value2');
map.set(true, 'value3');
const objKey = { id: 1 };
map.set(objKey, 'value4');

console.log(map.get(objKey));  // "value4"
console.log(map.size);         // 4

// 遍历(保证插入顺序)
for (const [key, value] of map) {
  console.log(key, value);
}

// 链式调用
new Map()
  .set('a', 1)
  .set('b', 2)
  .set('c', 3);

// Map 与 Object 互转
const obj = Object.fromEntries(map); // Map → Object(键会被转为字符串)
const map2 = new Map(Object.entries(obj)); // Object → Map
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
特性 Object Map
键类型 仅 String/Symbol 任意类型
键顺序 不保证(整数键排前面) 保证插入顺序
大小 Object.keys(o).length map.size
迭代 不可直接迭代 可直接 for...of
性能 频繁增删较慢 频繁增删更优
原型键 有(toString 等) 无

# 6.1.4 Set

Set:存储唯一值的集合(自动去重)。

const set = new Set([1, 2, 3, 3, 2, 1]);
console.log(set); // Set {1, 2, 3}
console.log(set.size); // 3

set.add(4);
set.delete(1);
console.log(set.has(2)); // true

// 数组去重的最简写法
const unique = [...new Set([1, 1, 2, 3, 3])]; // [1, 2, 3]

// 集合运算(ES2025 提案,部分引擎已支持)
const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);

// 交集
const intersection = new Set([...a].filter(x => b.has(x))); // {2, 3}
// 并集
const union = new Set([...a, ...b]); // {1, 2, 3, 4}
// 差集
const diff = new Set([...a].filter(x => !b.has(x))); // {1}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Set 判断唯一性的算法:Set 内部使用类似 === 的比较,但特殊处理了 NaN——在 Set 中 NaN 等于 NaN:

const set = new Set();
set.add(NaN);
set.add(NaN); // 不会重复添加
console.log(set.size); // 1
console.log(set.has(NaN)); // true
1
2
3
4
5

# 6.1.5 WeakMap和WeakSet

WeakMap 和 WeakSet:弱引用版本的 Map 和 Set。

弱引用的核心概念:WeakMap/WeakSet 中的键(WeakMap)或值(WeakSet)是弱引用——不会阻止垃圾回收。如果一个对象只被 WeakMap 引用,GC 可以回收它。

// WeakMap 典型应用:存储私有数据
const privateData = new WeakMap();

class Person {
  constructor(name, secret) {
    privateData.set(this, { secret });
    this.name = name;
  }
  getSecret() {
    return privateData.get(this).secret;
  }
}

let person = new Person("Alice", "my-password");
console.log(person.getSecret()); // "my-password"
person = null; // person 被回收后,WeakMap 中对应的条目也会被自动清理

// WeakMap 典型应用:DOM 节点关联数据
const nodeData = new WeakMap();
const element = document.createElement('div');
nodeData.set(element, { clickCount: 0 });
// 当 element 从 DOM 移除并失去所有引用时,关联数据自动清理

// WeakSet 典型应用:标记已处理的对象
const processed = new WeakSet();
function processOnce(obj) {
  if (processed.has(obj)) return;
  processed.add(obj);
  console.log('Processing:', obj);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

WeakMap/WeakSet 的限制:

  • 键只能是对象(不能是原始类型)
  • 不可迭代(没有 size、forEach、keys 等方法)
  • 不可清空(没有 clear 方法)

# 6.2 特殊数据类型

# 6.2.1 Date

Date:处理日期和时间。JavaScript 的 Date 对象基于 Unix 时间戳(1970年1月1日 UTC 起的毫秒数)。

// 创建方式
const now = new Date();                    // 当前时间
const specific = new Date(2024, 0, 15);    // 2024年1月15日(月份从0开始!)
const fromString = new Date('2024-01-15'); // ISO 格式字符串
const fromTimestamp = new Date(1705276800000); // 时间戳

// 常用方法
console.log(now.getFullYear());  // 2024
console.log(now.getMonth());     // 0-11(注意:0 = 一月)
console.log(now.getDate());      // 1-31
console.log(now.getDay());       // 0-6(0 = 星期日)
console.log(now.getTime());      // 时间戳(毫秒)

// 时间计算
const future = new Date();
future.setDate(future.getDate() + 7); // 7天后

// 时间差
const start = new Date('2024-01-01');
const end = new Date('2024-12-31');
const diffMs = end - start; // 毫秒差
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); // 365

// 高精度计时
const t0 = performance.now(); // 比 Date.now() 精度更高
// ... 执行代码 ...
const t1 = performance.now();
console.log(`耗时: ${t1 - t0}ms`);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

Date 的陷阱:月份从 0 开始(0=一月),new Date(2024, 1, 15) 是2月15日而非1月15日。

# 6.2.2 RegExp

RegExp:处理正则表达式,用于模式匹配和文本替换。

正则表达式的底层原理:JavaScript 正则引擎使用**回溯法(Backtracking)的 NFA(非确定性有限自动机)实现。V8 中有两套正则引擎:Irregexp(解释执行)和 JIT 编译版本(对热点正则进行编译优化)。理解回溯行为对避免灾难性回溯(Catastrophic Backtracking)**非常重要。

// 创建方式
const re1 = /hello/gi;                    // 字面量(推荐)
const re2 = new RegExp('hello', 'gi');     // 构造函数

// 常用方法
const str = 'Hello World, hello JavaScript';
console.log(re1.test(str));   // true(是否匹配)
console.log(re1.exec(str));   // 匹配详情(含 index)

// 字符串方法配合正则
console.log(str.match(/hello/gi));      // ["Hello", "hello"]
console.log(str.replace(/hello/gi, 'Hi')); // "Hi World, Hi JavaScript"
console.log(str.search(/world/i));      // 6(首次匹配位置)
console.log(str.split(/,\s*/));         // ["Hello World", "hello JavaScript"]

// 命名捕获组(ES2018)
const dateRe = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = '2024-01-15'.match(dateRe);
console.log(match.groups.year);  // "2024"
console.log(match.groups.month); // "01"

// matchAll(ES2020)—— 获取所有匹配
const text = 'cat bat hat';
for (const m of text.matchAll(/[a-z]at/g)) {
  console.log(m[0], m.index); // "cat" 0, "bat" 4, "hat" 8
}

// 灾难性回溯的例子(避免这样写!)
// /^(a+)+$/.test('aaaaaaaaaaaaaaaaaaaab'); // 极慢!指数级回溯
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 6.2.3 Error

Error:处理错误对象,详见第9章错误机制。

// 内置错误类型
try {
  undeclaredVar;        // ReferenceError
} catch (e) {
  console.log(e.name);    // "ReferenceError"
  console.log(e.message); // "undeclaredVar is not defined"
  console.log(e.stack);   // 完整堆栈信息
}

// 常见错误类型
// SyntaxError: 语法错误(解析时)
// TypeError: 类型错误(如调用非函数)
// RangeError: 范围错误(如数组长度为负)
// ReferenceError: 引用错误(如访问未声明的变量)
// URIError: URI 处理错误
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 6.3 全局对象

# 6.3.1 Math

Math:提供数学运算功能。Math 不是构造函数,所有方法都是静态的。

// 常用常量
Math.PI;      // 3.141592653589793
Math.E;       // 2.718281828459045

// 常用方法
Math.random();           // [0, 1) 随机数
Math.floor(4.7);         // 4(向下取整)
Math.ceil(4.2);          // 5(向上取整)
Math.round(4.5);         // 5(四舍五入)
Math.trunc(4.9);         // 4(截断小数部分)
Math.max(1, 5, 3);       // 5
Math.min(1, 5, 3);       // 1
Math.abs(-5);            // 5
Math.pow(2, 10);         // 1024
Math.sqrt(16);           // 4
Math.log2(8);            // 3

// 生成指定范围的随机整数
function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(randomInt(1, 100)); // 1-100 之间的随机整数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 6.3.2 JSON

JSON:处理 JSON 数据的序列化和反序列化。

JSON 的设计原理:JSON(JavaScript Object Notation)由 Douglas Crockford 在 2001 年提出,它是 JavaScript 对象字面量语法的一个严格子集。JSON 之所以成为 Web 数据交换的事实标准,是因为它足够简单、自描述、语言无关。

const data = {
  name: "Alice",
  age: 25,
  hobbies: ["reading", "coding"],
  address: { city: "Beijing" }
};

// 序列化
const json = JSON.stringify(data);
console.log(json);
// '{"name":"Alice","age":25,"hobbies":["reading","coding"],"address":{"city":"Beijing"}}'

// 格式化输出
console.log(JSON.stringify(data, null, 2)); // 2空格缩进

// replacer 函数:自定义序列化
const filtered = JSON.stringify(data, (key, value) => {
  if (key === 'age') return undefined; // 排除 age
  return value;
});

// 反序列化
const parsed = JSON.parse(json);

// reviver 函数:自定义反序列化
const withDate = '{"date":"2024-01-15T00:00:00.000Z"}';
const obj = JSON.parse(withDate, (key, value) => {
  if (key === 'date') return new Date(value);
  return value;
});

// JSON.stringify 不能序列化的值
JSON.stringify(undefined);     // undefined(被忽略)
JSON.stringify(function(){});  // undefined
JSON.stringify(Symbol());      // undefined
JSON.stringify(NaN);           // "null"
JSON.stringify(Infinity);      // "null"
// 循环引用会抛出 TypeError

// toJSON 方法:自定义序列化行为
class User {
  constructor(name, password) {
    this.name = name;
    this.password = password;
  }
  toJSON() {
    return { name: this.name }; // 序列化时排除密码
  }
}
console.log(JSON.stringify(new User("Alice", "123"))); // {"name":"Alice"}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

# 6.3.3 Promise

Promise:处理异步操作(详见第7章异步操作)。

// 快捷创建
const resolved = Promise.resolve(42);
const rejected = Promise.reject(new Error('fail'));

// 静态方法
Promise.all([p1, p2, p3]);        // 全部成功才成功
Promise.allSettled([p1, p2, p3]);  // 等待全部完成(无论成败)
Promise.race([p1, p2, p3]);       // 取最先完成的
Promise.any([p1, p2, p3]);        // 取最先成功的(ES2021)
1
2
3
4
5
6
7
8
9

# 6.3.4 Proxy

Proxy:创建对象的代理,拦截对象的基本操作。

Proxy 的设计原理:Proxy 是 ES6 引入的元编程(Metaprogramming)特性,它基于 ECMAScript 规范定义的内部方法(Internal Methods)。每个 JavaScript 对象都有 [[Get]]、[[Set]]、[[Delete]] 等内部方法,Proxy 允许你拦截并自定义这些方法的行为。Vue 3 的响应式系统就是基于 Proxy 实现的。

// 基础用法
const handler = {
  get(target, prop, receiver) {
    console.log(`读取属性: ${prop}`);
    return Reflect.get(target, prop, receiver);
  },
  set(target, prop, value, receiver) {
    console.log(`设置属性: ${prop} = ${value}`);
    return Reflect.set(target, prop, value, receiver);
  }
};

const person = new Proxy({ name: "Alice" }, handler);
person.name;        // 读取属性: name → "Alice"
person.age = 25;    // 设置属性: age = 25

// 实际应用:数据验证
function createValidated(schema) {
  return new Proxy({}, {
    set(target, prop, value) {
      const validator = schema[prop];
      if (validator && !validator(value)) {
        throw new TypeError(`Invalid value for ${prop}: ${value}`);
      }
      target[prop] = value;
      return true;
    }
  });
}

const user = createValidated({
  name: v => typeof v === 'string' && v.length > 0,
  age: v => typeof v === 'number' && v >= 0 && v <= 150,
  email: v => /^\S+@\S+\.\S+$/.test(v)
});

user.name = "Alice";  // OK
user.age = 25;         // OK
// user.age = -1;      // TypeError: Invalid value for age: -1

// 实际应用:负索引数组
function createNegativeArray(arr) {
  return new Proxy(arr, {
    get(target, prop) {
      const index = Number(prop);
      if (index < 0) {
        return target[target.length + index];
      }
      return target[prop];
    }
  });
}

const arr = createNegativeArray([1, 2, 3, 4, 5]);
console.log(arr[-1]); // 5
console.log(arr[-2]); // 4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

# 6.3.5 Reflect

Reflect:提供操作对象的静态方法,与 Proxy 的 handler 方法一一对应。

const obj = { x: 1, y: 2 };

// Reflect 方法与旧语法的对应关系
Reflect.get(obj, 'x');               // 等价于 obj.x
Reflect.set(obj, 'z', 3);            // 等价于 obj.z = 3
Reflect.has(obj, 'x');               // 等价于 'x' in obj
Reflect.deleteProperty(obj, 'x');    // 等价于 delete obj.x
Reflect.ownKeys(obj);                // 返回所有自身属性(包括 Symbol)

// Reflect 的优势:返回布尔值表示操作是否成功,而不是抛出异常
const frozen = Object.freeze({ a: 1 });
console.log(Reflect.set(frozen, 'a', 2)); // false(而 frozen.a = 2 静默失败)
1
2
3
4
5
6
7
8
9
10
11
12

# 6.4 全局函数

# 6.4.1 eval

eval():执行字符串中的 JavaScript 代码。

eval('2 + 2'); // 4
eval('console.log("Hello")'); // 输出 Hello
1
2

安全警告:eval 存在严重的安全风险和性能问题:

  • 安全风险:可以执行任意代码,容易被注入攻击
  • 性能问题:使用 eval 会导致 V8 无法优化当前作用域(因为无法预知 eval 会访问/修改哪些变量)
  • 调试困难:eval 中的代码不会出现在正常的调用栈中

替代方案:JSON.parse() 解析 JSON,Function() 构造函数创建函数,new Map() 代替动态属性名。

# 6.4.2 isNaN

isNaN() 和 Number.isNaN():检查值是否为 NaN。

// 全局 isNaN(有类型转换,容易误判)
isNaN(NaN);       // true
isNaN("hello");   // true("hello" 转为 NaN)
isNaN(undefined); // true(undefined 转为 NaN)

// Number.isNaN(严格判断,推荐使用)
Number.isNaN(NaN);       // true
Number.isNaN("hello");   // false
Number.isNaN(undefined); // false
1
2
3
4
5
6
7
8
9

# 6.4.3 isFinite

isFinite():检查值是否为有限数。

isFinite(42);       // true
isFinite(Infinity); // false
isFinite(NaN);      // false

// Number.isFinite 更严格(不做类型转换)
Number.isFinite("42"); // false
isFinite("42");         // true("42" 转为 42)
1
2
3
4
5
6
7

# 6.4.4 parseInt

parseInt() 和 parseFloat():将字符串转换为整数或浮点数。

parseInt('42');        // 42
parseInt('42px');      // 42(解析到非数字字符为止)
parseInt('0xFF', 16);  // 255(指定基数)
parseInt('111', 2);    // 7(二进制)

parseFloat('3.14');    // 3.14
parseFloat('3.14.15'); // 3.14(只解析第一个小数点)

// 常见陷阱
parseInt('08');         // 8(曾经在旧引擎中为 0,因为被当作八进制)
parseInt(0.0000005);   // 5!(0.0000005 先转为 "5e-7",parseInt 解析 "5")
1
2
3
4
5
6
7
8
9
10
11

# 6.4.5 encodeURI

encodeURI() 和 decodeURI():编码/解码完整 URI,保留 URI 结构字符(/、?、#、& 等)。

const uri = 'https://example.com/路径?name=张三&age=25';
const encoded = encodeURI(uri);
console.log(encoded);
// "https://example.com/%E8%B7%AF%E5%BE%84?name=%E5%BC%A0%E4%B8%89&age=25"
console.log(decodeURI(encoded)); // 还原
1
2
3
4
5

# 6.4.6 encodeURIComponent

encodeURIComponent() 和 decodeURIComponent():编码/解码 URI 组件,会编码所有特殊字符(包括 /、?、& 等)。

const param = 'name=张三&city=北京';
const encoded = encodeURIComponent(param);
console.log(encoded);
// "name%3D%E5%BC%A0%E4%B8%89%26city%3D%E5%8C%97%E4%BA%AC"

// 典型使用场景:构建查询参数
const url = `https://api.example.com/search?q=${encodeURIComponent('hello world&more')}`;
1
2
3
4
5
6
7

encodeURI vs encodeURIComponent:

  • encodeURI:编码整个 URL,保留 ://、/、?、#、& 等
  • encodeURIComponent:编码参数值,会编码上述所有字符

# 6.5 浏览器相关

# 6.5.1 Window

  • 表示浏览器窗口,是浏览器环境中的全局对象。
  • 属性:window.document、window.location、window.localStorage。
  • 所有全局变量和函数都是 window 的属性。
// window 就是全局对象
var x = 1;
console.log(window.x); // 1

// 常用属性
console.log(window.innerWidth);  // 视口宽度
console.log(window.innerHeight); // 视口高度
console.log(window.devicePixelRatio); // 设备像素比

// 常用方法
window.alert('Hello');
window.confirm('确定?'); // 返回 boolean
window.prompt('请输入:'); // 返回字符串或 null

// 定时器(实际上是 window 的方法)
window.setTimeout(() => {}, 1000);
window.setInterval(() => {}, 1000);
window.requestAnimationFrame(() => {}); // 动画首选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 6.5.2 Document

  • 表示 HTML 文档,是 DOM 树的根节点。
// 查找元素
document.getElementById('app');
document.querySelector('.class');
document.querySelectorAll('div');

// 创建元素
const div = document.createElement('div');
div.textContent = 'Hello';
div.className = 'my-class';
document.body.appendChild(div);

// DOM 操作性能优化:使用 DocumentFragment
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
  const li = document.createElement('li');
  li.textContent = `Item ${i}`;
  fragment.appendChild(li); // 不触发重排
}
document.getElementById('list').appendChild(fragment); // 一次性插入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 6.5.3 Navigator

  • 提供浏览器信息。
console.log(navigator.userAgent);     // 浏览器标识
console.log(navigator.language);      // 语言
console.log(navigator.onLine);        // 是否在线
console.log(navigator.hardwareConcurrency); // CPU 核心数

// 现代 API
navigator.clipboard.writeText('复制内容'); // 复制到剪贴板
navigator.geolocation.getCurrentPosition(pos => {
  console.log(pos.coords.latitude, pos.coords.longitude);
});
1
2
3
4
5
6
7
8
9
10

# 6.5.4 Location

  • 提供当前页面的 URL 信息和导航控制。
// URL 解析
console.log(location.href);     // 完整 URL
console.log(location.protocol); // "https:"
console.log(location.host);     // "example.com:8080"
console.log(location.hostname); // "example.com"
console.log(location.port);     // "8080"
console.log(location.pathname); // "/path/to/page"
console.log(location.search);   // "?key=value"
console.log(location.hash);     // "#section"

// 导航
location.href = 'https://example.com'; // 跳转(有历史记录)
location.replace('https://example.com'); // 替换(无历史记录)
location.reload(); // 刷新

// URLSearchParams(现代 API)
const params = new URLSearchParams(location.search);
params.get('key');
params.set('key', 'newValue');
params.append('key2', 'value2');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 6.5.5 History

  • 提供浏览器历史记录操作,SPA 路由的基础。
history.back();       // 后退
history.forward();    // 前进
history.go(-2);       // 后退2页

// pushState / replaceState(SPA 核心)
history.pushState({ page: 1 }, 'title', '/page1'); // 添加历史记录
history.replaceState({ page: 2 }, 'title', '/page2'); // 替换当前记录

// 监听历史变化
window.addEventListener('popstate', (event) => {
  console.log('导航到:', location.pathname, event.state);
});
1
2
3
4
5
6
7
8
9
10
11
12

# 6.5.6 Storage

提供本地存储功能,数据持久化在浏览器中。

// localStorage:永久存储(除非手动清除)
localStorage.setItem('user', JSON.stringify({ name: 'Alice' }));
const user = JSON.parse(localStorage.getItem('user'));
localStorage.removeItem('user');
localStorage.clear(); // 清除所有

// sessionStorage:会话存储(关闭标签页即清除)
sessionStorage.setItem('token', 'abc123');

// 限制:通常 5-10MB,只能存储字符串
// 监听存储变化(跨标签页通信)
window.addEventListener('storage', (event) => {
  console.log('存储变化:', event.key, event.oldValue, event.newValue);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 6.5.7 Fetch

Fetch API 是现代的网络请求 API,替代 XMLHttpRequest。

// GET 请求
const response = await fetch('https://api.example.com/users');
const data = await response.json();

// POST 请求
const result = await fetch('https://api.example.com/users', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'Alice' })
});

// 注意:fetch 不会在 HTTP 错误状态(404、500)时 reject
// 需要手动检查 response.ok
if (!response.ok) {
  throw new Error(`HTTP error! status: ${response.status}`);
}

// 超时控制(使用 AbortController)
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000); // 5秒超时

try {
  const res = await fetch(url, { signal: controller.signal });
} catch (err) {
  if (err.name === 'AbortError') console.log('请求超时');
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 6.5.8 WebSocket

用于实现全双工实时通信。

const ws = new WebSocket('wss://example.com/socket');

ws.onopen = () => {
  console.log('连接已建立');
  ws.send(JSON.stringify({ type: 'hello' }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('收到消息:', data);
};

ws.onerror = (error) => console.error('WebSocket 错误:', error);
ws.onclose = () => console.log('连接已关闭');

// 关闭连接
ws.close(1000, '正常关闭');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 6.6 国际化与本地化

# 6.6.1 Intl

  • 提供国际化功能,支持日期、数字、货币等的本地化格式。
// 数字格式化
const numFmt = new Intl.NumberFormat('zh-CN', {
  style: 'currency',
  currency: 'CNY'
});
console.log(numFmt.format(1234567.89)); // "¥1,234,567.89"

// 日期格式化
const dateFmt = new Intl.DateTimeFormat('zh-CN', {
  year: 'numeric',
  month: 'long',
  day: 'numeric',
  weekday: 'long'
});
console.log(dateFmt.format(new Date())); // "2024年1月15日星期一"

// 相对时间(ES2020)
const rtf = new Intl.RelativeTimeFormat('zh-CN', { numeric: 'auto' });
console.log(rtf.format(-1, 'day'));   // "昨天"
console.log(rtf.format(2, 'hour'));   // "后天"
console.log(rtf.format(-3, 'month')); // "3个月前"

// 列表格式化
const listFmt = new Intl.ListFormat('zh-CN', { type: 'conjunction' });
console.log(listFmt.format(['苹果', '香蕉', '橘子'])); // "苹果、香蕉和橘子"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 6.6.2 toLocaleString

  • 根据本地化规则格式化数据。
// 数字
(1234567.89).toLocaleString('zh-CN'); // "1,234,567.89"
(0.75).toLocaleString('zh-CN', { style: 'percent' }); // "75%"

// 日期
new Date().toLocaleString('zh-CN'); // "2024/1/15 14:30:00"
new Date().toLocaleDateString('zh-CN'); // "2024/1/15"
new Date().toLocaleTimeString('zh-CN'); // "14:30:00"
1
2
3
4
5
6
7
8

# 6.7 二进制与文件

# 6.7.1 ArrayBuffer

表示通用的二进制数据缓冲区,不能直接操作,需要通过**视图(TypedArray 或 DataView)**访问。

// 创建 8 字节缓冲区
const buffer = new ArrayBuffer(8);

// 通过 TypedArray 操作
const int32View = new Int32Array(buffer);
int32View[0] = 42;
int32View[1] = 99;
console.log(int32View); // Int32Array [42, 99]

// 通过 DataView 操作(可指定字节序)
const view = new DataView(buffer);
view.setFloat64(0, 3.14);
console.log(view.getFloat64(0)); // 3.14
1
2
3
4
5
6
7
8
9
10
11
12
13

# 6.7.2 Blob

表示不可变的二进制数据对象,通常用于文件操作。

// 创建 Blob
const blob = new Blob(['Hello, World!'], { type: 'text/plain' });
console.log(blob.size); // 13
console.log(blob.type); // "text/plain"

// 生成下载链接
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'hello.txt';
a.click();
URL.revokeObjectURL(url); // 释放内存
1
2
3
4
5
6
7
8
9
10
11
12

# 6.7.3 File

表示文件对象,继承自 Blob,通常来自 <input type="file"> 或拖放操作。

document.querySelector('input[type="file"]').addEventListener('change', (e) => {
  const file = e.target.files[0];
  console.log(file.name);         // 文件名
  console.log(file.size);         // 大小(字节)
  console.log(file.type);         // MIME 类型
  console.log(file.lastModified); // 最后修改时间戳
});
1
2
3
4
5
6
7

# 6.7.4 FileReader

读取文件内容。

const reader = new FileReader();

reader.onload = (e) => {
  console.log(e.target.result); // 文件内容
};

reader.onerror = (e) => {
  console.error('读取失败:', e);
};

// 不同的读取方式
reader.readAsText(file);         // 读取为文本
reader.readAsDataURL(file);      // 读取为 Base64 Data URL
reader.readAsArrayBuffer(file);  // 读取为 ArrayBuffer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
上次更新: 2026/06/10, 11:13:41
面向对象
异步操作

← 面向对象 异步操作→

最近更新
01
信号崩溃快速排查
06-15
02
CoreDump破案
06-15
03
perf火焰图实战
06-15
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式