跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScriptNode.js大前端java

深入解析 Cannot read properties of undefined 报错:从根源定位到根治方案

空值访问错误是开发中最常见的陷阱之一。剖析 Cannot read properties of undefined 报错的本质,区分 undefined 与 null 的差异。通过 DOM 加载时序、接口数据异常、数组越界、异步闭包等高频场景,展示如何快速定位根因。提供可选链、默认值、类型校验及团队协作规范等根治方案,帮助开发者从被动修复转向主动预防,构建更健壮的代码逻辑。

2177283801发布于 2026/4/9更新于 2026/5/2218 浏览

Uncaught TypeError: Cannot read properties of undefined (reading 'xxx'):从报错根源到根治方案

引言:被'undefined'支配的恐惧

如果你是开发者,大概率在控制台见过这句红色报错——"Uncaught TypeError: Cannot read properties of undefined (reading 'xxx')"(或后端类似"Cannot read field 'xxx' of null")。这类空值访问错误在日常开发中非常普遍,尤其在复杂业务场景下,往往需要逐层排查才能定位根因。

但多数开发者解决这类报错时,只停留在'加个 if 判断'的表层修复,未深究'为什么会出现 undefined',导致同类问题反复出现。本文将从报错本质、常见场景、分步排查、根治方案及实战案例五个维度,彻底解决这类空值访问错误,不仅教你怎么修,更教你怎么防。

一、报错本质:为什么会'Cannot read properties of undefined'?

在解决问题前,必须先理解报错的核心逻辑——当你试图访问一个值为 undefined 或 null 的变量的属性或方法时,JavaScript 及类似弱类型语言就会抛出这类错误。

举个最直观的例子:

// 场景 1:变量未赋值(值为 undefined)
let user;
console.log(user.name); // 报错:Cannot read properties of undefined (reading 'name')

// 场景 2:变量赋值为 null
let user = null;
console.log(user.age); // 报错:Cannot read properties of null (reading 'age')

// 场景 3:嵌套对象中的某一层为 undefined
let data = { user: undefined };
console.log(data.user.address.city); // 报错:Cannot read properties of undefined (reading 'address')
关键区别:undefined vs null

很多人会混淆这两个值,但它们的场景不同,排查方向也不同:

  • undefined:变量'声明了但未赋值',或'访问对象不存在的属性'(如 obj.xxx 中 xxx 不存在),或'函数未返回值'(默认返回 undefined);
  • null:变量'主动赋值为 null',表示'刻意为空'(如后端接口返回 null 表示'无数据'),或'DOM 查询未找到元素'(如 document.getElementById('xxx') 返回 null)。

无论哪种情况,核心问题都是'访问了空值的属性',但根因需要结合具体场景分析。

二、高频场景与根因分析(前端 + 后端全覆盖)

这类报错的出现,绝非偶然,而是业务逻辑或代码规范的漏洞。以下是 6 个最常见的场景,覆盖前后端开发,每个场景都附带错误代码和根因拆解。

场景 1:前端 DOM 操作——元素未加载就访问
错误代码(前端/Vue/React 通用)
<!-- 错误示例:脚本在 DOM 加载前执行 -->
<script>
  // 此时<body>还未加载,getElementById 返回 null
  const btn = document.getElementById('submit-btn'); 
  btn.addEventListener('click', () => {
    console.log('点击了按钮');
  });
</script>
<body>
  <button id="submit-btn">提交</button>
</body>
根因
  • 浏览器解析 HTML 时,按'自上而下'顺序执行代码;
  • 脚本在 <body> 前执行时,submit-btn 元素还未被解析,getElementById 返回 null,后续访问 addEventListener 自然报错。
场景 2:接口返回数据结构异常(前后端协作高频坑)
错误代码(前端/Vue3 示例)
<template>
  <div>用户姓名:{{ userInfo.name }}</div>
  <div>用户地址:{{ userInfo.address.city }}</div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
const userInfo = ref({});

onMounted(async () => {
  // 假设接口因异常,返回 { userInfo: undefined }(而非预期的完整对象)
  const res = await fetch('/api/user');
  const data = await res.json();
  userInfo.value = data.userInfo; // userInfo.value 变为 undefined
});
</script>
根因
  • 后端问题:接口未按约定返回数据(如字段缺失、数据类型错误、异常时返回 undefined);
  • 前端问题:未对接口返回数据做'类型校验'和'默认值处理',直接假设数据结构符合预期。
场景 3:数组越界访问(前端列表渲染/后端数据处理)
错误代码(前端/React 示例)
function UserList({ users }) {
  // 假设 users 是长度为 2 的数组,访问索引 2 会返回 undefined
  const thirdUser = users[2];
  return (
    <div>
      <p>第三个用户:{thirdUser.name}</p> {/* 报错:Cannot read properties of undefined (reading 'name') */}
    </div>
  );
}

// 调用组件时传递的 users 数组长度不足
<UserList users={[{ name: '张三' }, { name: '李四' }]} />
根因
  • 数组索引超出实际长度(如长度为 n 的数组,索引最大为 n-1),访问不存在的索引返回 undefined;
  • 未判断数组长度或索引有效性,直接假设'数组有足够多的元素'。
场景 4:闭包/异步操作中的变量生命周期问题(前端高频)
错误代码(前端/JavaScript 异步示例)
// 循环中创建异步函数,访问循环变量
for (var i = 0; i < 3; i++) {
  setTimeout(() => {
    // 循环结束后 i 变为 3,arr[3] 为 undefined
    const arr = [10, 20, 30];
    console.log(arr[i].toString()); // 报错:Cannot read properties of undefined (reading 'toString')
  }, 1000);
}
根因
  • var 声明的变量没有块级作用域,循环结束后 i 的值变为 3(超出数组 arr 的索引范围);
  • 异步函数(setTimeout)执行时,循环已结束,访问 arr[i] 即 arr[3],返回 undefined。
场景 5:后端 JSON 解析后字段缺失(Java/Node.js 示例)
错误代码(后端/Node.js 示例)
// 假设前端传递的 JSON 为:{ "orderId": "123", "user": { "name": "张三" } }
// 后端解析后,试图访问 user.address(但前端未传递 address 字段)
app.post('/api/order', (req, res) => {
  const order = req.body;
  // 直接访问 order.user.address,若 address 不存在,order.user.address 为 undefined
  const city = order.user.address.city; // 报错:Cannot read properties of undefined (reading 'city')
  res.send({ status: 'success', city });
});
根因
  • 前后端未约定'必填字段'和'可选字段',前端未传递可选字段时,后端直接访问嵌套属性;
  • 后端未对解析后的 JSON 做'字段存在性校验',默认假设所有字段都存在。
场景 6:函数参数未传默认值(前后端通用)
错误代码(前端/后端通用)
// 函数假设参数 obj 有 name 属性,但调用时未传参数(obj 为 undefined)
function printName(obj) {
  console.log(obj.name); // 报错:Cannot read properties of undefined (reading 'name')
}

// 调用函数时未传参数
printName();
根因
  • 函数未设置参数默认值,调用时未传参,参数默认值为 undefined;
  • 函数内部未判断参数是否为 undefined,直接访问其属性。

三、分步排查:从'报错'到'定位根因'的 5 步法

遇到这类报错时,不要慌着加 if (obj),先按以下步骤定位根因,才能彻底解决问题:

步骤 1:复制报错信息,确定'哪个变量是 undefined'

报错信息会明确告诉你'哪个变量的哪个属性'出了问题。例如:

  • 'Cannot read properties of undefined (reading 'city')' → 说明'访问某个变量的 city 属性时,该变量是 undefined';
  • 结合代码上下文,找到报错行(如 const city = order.user.address.city),判断'order.user.address'是 undefined。
步骤 2:打印变量值,确认'为什么是 undefined'

在报错行前,打印关键变量的值,看是否符合预期:

// 前端示例:打印 order.user.address
console.log('order.user:', order.user);
console.log('order.user.address:', order.user.address); // 看是否为 undefined

// 后端示例(Node.js):打印 req.body
console.log('请求体:', req.body);
console.log('user.address:', req.body.user.address);
步骤 3:追溯变量来源,定位'源头问题'

变量的来源通常有 3 种,对应不同的排查方向:

  1. 用户输入/DOM 元素:检查是否'元素未加载'或'输入为空';
  2. 接口返回数据:检查接口文档,看返回数据是否符合约定(用 Postman 重新请求接口);
  3. 函数参数/内部变量:检查函数调用时是否传参,内部变量赋值是否正确。
步骤 4:判断'是偶发还是必现',缩小范围
  • 必现报错:代码逻辑有明确漏洞(如变量未赋值、数组越界),直接定位报错行即可;
  • 偶发报错:可能是'异步数据不稳定'(如接口有时返回正常,有时返回异常),需结合日志排查(如前端 console.log 接口返回,后端打印请求体)。
步骤 5:验证根因,避免'治标不治本'

找到疑似根因后,做小范围修改验证:

  • 若怀疑'接口返回数据缺失',用 Postman 模拟返回缺失字段,看是否复现报错;
  • 若怀疑'DOM 未加载',将脚本移到 <body> 末尾,看是否解决问题。

四、根治方案:从'修复报错'到'避免再犯'(分场景解决)

针对不同场景,除了'临时修复',更要给出'根治方案',避免同类问题反复出现。

场景 1:DOM 操作未加载 → 确保脚本在 DOM 加载后执行
方案 1:将脚本移到 <body> 末尾
<body>
  <button id="submit-btn">提交</button>
  <!-- 脚本在 DOM 之后执行 -->
  <script>
    const btn = document.getElementById('submit-btn');
    btn.addEventListener('click', () => {
      console.log('点击了按钮');
    });
  </script>
</body>
方案 2:监听 DOMContentLoaded 事件(推荐)
// 等待 DOM 完全加载后执行
document.addEventListener('DOMContentLoaded', () => {
  const btn = document.getElementById('submit-btn');
  btn?.addEventListener('click', () => {
    // 加可选链,双重保险
    console.log('点击了按钮');
  });
});
场景 2:接口返回数据异常 → 加'类型校验 + 默认值'
方案 1:前端用'可选链(?.)+ 空值合并(??)'处理
<script setup>
import { ref, onMounted } from 'vue';
const userInfo = ref({
  // 设置默认值,避免 undefined
  address: { city: '未知城市' }
});

onMounted(async () => {
  const res = await fetch('/api/user');
  const data = await res.json();
  // 可选链:data.userInfo 不存在时返回 undefined,不报错
  // 空值合并:若 data.userInfo 为 undefined,用默认的 userInfo.value
  userInfo.value = data.userInfo ?? userInfo.value;
});
</script>

<template>
  <!-- 模板中也可使用可选链(Vue3/React 均支持) -->
  <div>用户地址:{{ userInfo?.address?.city ?? '未知城市' }}</div>
</template>
方案 2:用 TypeScript 定义接口,强制类型校验(根治)
// 定义 UserInfo 接口,明确字段类型和可选性
interface Address {
  city: string;
  street?: string; // 可选字段
}

interface UserInfo {
  name: string;
  address: Address; // 必选字段,确保有 address
}

// 接口返回数据必须符合 UserInfo 类型,否则编译报错
async function fetchUser(): Promise<UserInfo> {
  const res = await fetch('/api/user');
  const data = await res.json();
  // 类型断言 + 简单校验,不符合则抛出错误
  if (!data.userInfo?.address?.city) {
    throw new Error('接口返回数据缺少 address.city');
  }
  return data.userInfo as UserInfo;
}
场景 3:数组越界访问 → 先判断长度或索引
方案 1:访问前判断索引有效性
function UserList({ users }) {
  // 判断索引 2 是否在数组范围内
  const thirdUser = users.length > 2 ? users[2] : { name: '无此用户' };
  return (
    <div>
      <p>第三个用户:{thirdUser.name}</p>
    </div>
  );
}
方案 2:用数组方法(find/filter)替代索引访问(推荐)
// 需求:找到 id 为 3 的用户,而非访问索引 2
const users = [
  { id: 1, name: '张三' },
  { id: 2, name: '李四' }
];

// find 返回匹配的元素,若无匹配返回 undefined,用空值合并设默认值
const targetUser = users.find(user => user.id === 3) ?? { name: '无此用户' };
console.log(targetUser.name); // 输出:无此用户
场景 4:闭包/异步变量生命周期 → 用块级作用域
方案 1:将 var 改为 let/const(块级作用域)
// let 有块级作用域,每次循环的 i 都是独立的
for (let i = 0; i < 3; i++) {
  setTimeout(() => {
    const arr = [10, 20, 30];
    console.log(arr[i].toString()); // 正常输出:10, 20, 30
  }, 1000);
}
方案 2:用 IIFE(立即执行函数)保留变量值(兼容旧环境)
for (var i = 0; i < 3; i++) {
  // IIFE 将当前 i 的值传入,保留在函数作用域中
  (function(index) {
    setTimeout(() => {
      const arr = [10, 20, 30];
      console.log(arr[index].toString());
    }, 1000);
  })(i);
}
场景 5:后端 JSON 字段缺失 → 加'字段校验 + 默认值'
方案 1:Node.js 用'可选链 + 默认值'处理
app.post('/api/order', (req, res) => {
  const order = req.body;
  // 可选链:order.user?.address 若 user 或 address 不存在,返回 undefined
  // 空值合并:若 address 不存在,默认值为 { city: '未知城市' }
  const address = order.user?.address ?? { city: '未知城市' };
  const city = address.city;
  res.send({ status: 'success', city });
});
方案 2:Java 用'Optional'类处理空值(根治)
import java.util.Optional;

// 定义 User 和 Address 类
class Address {
  private String city;
  // getter/setter
}

class User {
  private Address address;
  // getter/setter
}

class Order {
  private User user;
  // getter/setter
}

// 接口处理逻辑
@RequestMapping("/api/order")
public String handleOrder(@RequestBody Order order) {
  // 用 Optional 处理空值,避免直接访问
  String city = Optional.ofNullable(order)
    .map(Order::getUser)
    .map(User::getAddress)
    .map(Address::getCity)
    .orElse("未知城市"); // 空 Optional 时返回默认值
  return "{\"status\":\"success\",\"city\":\"" + city + "\"}";
}
场景 6:函数参数未传 → 设默认值 + 参数校验
方案 1:ES6+ 设置参数默认值
// 设置 obj 默认值为{},避免 undefined
function printName(obj = {}) {
  // 再加可选链,双重保险
  console.log(obj?.name ?? '未知姓名');
}

printName(); // 输出:未知姓名
printName({ name: '张三' }); // 输出:张三
方案 2:TypeScript 强制参数类型(根治)
// 定义参数类型,强制 obj 必须有 name 属性(或可选)
interface User {
  name: string;
  age?: number;
}

// 函数参数必须符合 User 类型,否则编译报错
function printName(obj: User) {
  console.log(obj.name);
}

// 调用时必须传符合 User 类型的参数,否则编译不通过
printName({ name: '张三' }); // 正常
printName(); // 编译报错:缺少参数 obj

五、实战案例:从'报错'到'根治'的完整流程

以'前端渲染用户地址时报错'为例,演示完整解决流程:

1. 报错现象

Vue 页面渲染时控制台报错:'Uncaught TypeError: Cannot read properties of undefined (reading 'city')',报错行:{{ userInfo.address.city }}。

2. 分步排查
  • 步骤 1:确定'userInfo.address'是 undefined;
  • 步骤 2:打印 userInfo 的值:console.log('userInfo:', userInfo.value),发现接口返回 { "name": "张三", "address": undefined };
  • 步骤 3:追溯来源:接口 /api/user 返回的 address 字段为 undefined,后端解释'用户未设置地址时,返回 undefined';
  • 步骤 4:判断必现:所有未设置地址的用户都会报错,属于必现问题;
  • 步骤 5:验证根因:用 Postman 请求接口,传递 { "hasAddress": false },返回 address 为 undefined,复现报错。
3. 根治方案
  • 前端临时修复:用可选链 + 默认值:{{ userInfo?.address?.city ?? '未设置地址' }};
  • 前后端长期约定:更新接口文档,明确'address 字段可选,未设置时返回 null 而非 undefined';
  • 前端类型校验:用 TypeScript 定义 UserInfo 接口,强制 address 为'Address | null',避免 undefined;
  • 后端数据处理:用户未设置地址时,返回 "address": null,而非不返回或返回 undefined。
4. 预防措施
  • 前端:在 api 请求工具中统一添加'数据校验中间件',对返回数据做基础校验;
  • 后端:用 Swagger 定义接口契约,明确必填/可选字段,返回空数据时用 null 而非 undefined。

六、预防体系:从'被动修复'到'主动避免'

解决这类报错的最高境界,是让它'不出现'。以下是 4 个层面的预防措施,覆盖团队协作、代码规范、工具链:

1. 团队协作:约定数据契约
  • 接口文档:用 Swagger/OpenAPI 明确'字段类型、必填/可选、默认值',避免'口头约定';
  • 空值约定:统一'空数据'的返回格式(如前端空数组用 [] 而非 null,空对象用 {} 而非 undefined);
  • 异常处理:约定接口异常时的返回格式(如 { "code": 500, "message": "错误信息", "data": null }),避免直接返回 undefined。
2. 代码规范:强制空值处理
  • 前端规范:
    • 所有嵌套属性访问必须用'可选链(?.)';
    • 数组索引访问前必须判断长度或索引有效性;
    • 函数参数必须设置默认值(尤其对象/数组类型)。
  • 后端规范:
    • Java 用 Optional 处理所有可能为 null 的字段;
    • Node.js 用'可选链 + 空值合并'处理 JSON 嵌套字段;
    • 避免直接返回 undefined(用 null 或默认值替代)。
3. 工具链:用 TypeScript/ESLint 强制约束
  • TypeScript:定义接口类型,编译阶段拦截'空值访问'错误(如 user: User | null,访问 user.name 时必须先判断非 null);
  • ESLint:启用 no-unsafe-optional-chaining(避免过度依赖可选链)、no-undef(禁止未声明变量)等规则;
  • 前端框架插件:Vue 用 vue-tsc、React 用 tsc 做编译阶段类型检查,提前发现问题。
4. 测试:覆盖边界场景
  • 单元测试:为'数据处理函数、接口请求函数'添加边界测试(如参数为 undefined、null、空数组);
  • E2E 测试:用 Cypress/Playwright 模拟'接口返回异常数据'的场景,验证页面是否正常渲染(而非报错);
  • 接口测试:用 Postman/Jest 测试'必填字段缺失、可选字段为空'的情况,确保后端返回正确格式。

七、总结:理解'空值',才能避免'空值错误'

'Cannot read properties of undefined (reading 'xxx')'这类报错,看似简单,实则暴露了'代码逻辑不严谨'或'团队协作无契约'的问题。解决它的关键,不是'加个 if 判断',而是:

  1. 理解根源:知道'为什么会出现 undefined',而非只解决表面问题;
  2. 分层处理:临时修复用'可选链 + 默认值',长期根治靠'类型校验 + 接口契约';
  3. 体系预防:通过团队约定、工具链约束、测试覆盖,让空值错误'不出现'。

记住:开发者的核心能力,不是'会修 bug',而是'能让 bug 不出现'。希望本文能帮你彻底摆脱'undefined 支配的恐惧',写出更健壮的代码。

目录

  1. Uncaught TypeError: Cannot read properties of undefined (reading 'xxx'):从报错根源到根治方案
  2. 引言:被“undefined”支配的恐惧
  3. 一、报错本质:为什么会“Cannot read properties of undefined”?
  4. 关键区别:undefined vs null
  5. 二、高频场景与根因分析(前端 + 后端全覆盖)
  6. 场景 1:前端 DOM 操作——元素未加载就访问
  7. 错误代码(前端/Vue/React 通用)
  8. 根因
  9. 场景 2:接口返回数据结构异常(前后端协作高频坑)
  10. 错误代码(前端/Vue3 示例)
  11. 根因
  12. 场景 3:数组越界访问(前端列表渲染/后端数据处理)
  13. 错误代码(前端/React 示例)
  14. 根因
  15. 场景 4:闭包/异步操作中的变量生命周期问题(前端高频)
  16. 错误代码(前端/JavaScript 异步示例)
  17. 根因
  18. 场景 5:后端 JSON 解析后字段缺失(Java/Node.js 示例)
  19. 错误代码(后端/Node.js 示例)
  20. 根因
  21. 场景 6:函数参数未传默认值(前后端通用)
  22. 错误代码(前端/后端通用)
  23. 根因
  24. 三、分步排查:从“报错”到“定位根因”的 5 步法
  25. 步骤 1:复制报错信息,确定“哪个变量是 undefined”
  26. 步骤 2:打印变量值,确认“为什么是 undefined”
  27. 步骤 3:追溯变量来源,定位“源头问题”
  28. 步骤 4:判断“是偶发还是必现”,缩小范围
  29. 步骤 5:验证根因,避免“治标不治本”
  30. 四、根治方案:从“修复报错”到“避免再犯”(分场景解决)
  31. 场景 1:DOM 操作未加载 → 确保脚本在 DOM 加载后执行
  32. 方案 1:将脚本移到 <body> 末尾
  33. 方案 2:监听 DOMContentLoaded 事件(推荐)
  34. 场景 2:接口返回数据异常 → 加“类型校验 + 默认值”
  35. 方案 1:前端用“可选链(?.)+ 空值合并(??)”处理
  36. 方案 2:用 TypeScript 定义接口,强制类型校验(根治)
  37. 场景 3:数组越界访问 → 先判断长度或索引
  38. 方案 1:访问前判断索引有效性
  39. 方案 2:用数组方法(find/filter)替代索引访问(推荐)
  40. 场景 4:闭包/异步变量生命周期 → 用块级作用域
  41. 方案 1:将 var 改为 let/const(块级作用域)
  42. 方案 2:用 IIFE(立即执行函数)保留变量值(兼容旧环境)
  43. 场景 5:后端 JSON 字段缺失 → 加“字段校验 + 默认值”
  44. 方案 1:Node.js 用“可选链 + 默认值”处理
  45. 方案 2:Java 用“Optional”类处理空值(根治)
  46. 场景 6:函数参数未传 → 设默认值 + 参数校验
  47. 方案 1:ES6+ 设置参数默认值
  48. 方案 2:TypeScript 强制参数类型(根治)
  49. 五、实战案例:从“报错”到“根治”的完整流程
  50. 1. 报错现象
  51. 2. 分步排查
  52. 3. 根治方案
  53. 4. 预防措施
  54. 六、预防体系:从“被动修复”到“主动避免”
  55. 1. 团队协作:约定数据契约
  56. 2. 代码规范:强制空值处理
  57. 3. 工具链:用 TypeScript/ESLint 强制约束
  58. 4. 测试:覆盖边界场景
  59. 七、总结:理解“空值”,才能避免“空值错误”
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • AI 大模型时代下易受影响的 20 种职业分析
  • Neo4j 5.26 版本安装、下载与配置步骤
  • 基于腾讯云 CVM 部署 Clawdbot 实现 Telegram 智能回复
  • GitHub 学生开发者包认证指南
  • WSL2 图形化支持:在 Windows 中运行 Ubuntu 桌面应用
  • Pandas 数据合并与拼接:merge、join 与 concat 详解
  • Python 爬虫项目:爬取 B 站直播弹幕数据
  • Spring Boot 部署优化:打包体积缩小 80% 的实践方案
  • FileSaver.js 实战解析:前端文件下载通用方案
  • 文本生成技术:原理、落地场景与国产工具实践
  • Python 中 argv 与 raw_input() 的区别详解
  • 基于麻雀搜索算法的 LSSVM 回归预测参数优化
  • 多材料 3D 打印软机器人:集成驱动与自主避障技术解析
  • Web 自动化测试入门:核心概念与百度搜索实战
  • Discord 机器人创建流程
  • 解决 GitHub SSH 连接端口 22 超时问题
  • Jenkins Pipeline 自动化构建与部署 Java 项目
  • GitHub Copilot Pro 学生身份认证与配置指南
  • Xilinx 7 Series FPGA 时钟设计
  • Python 数据科学工具链入门:NumPy、Pandas、Matplotlib 快速上手

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online