From 91d1cbce10f6869c4282ff9a995d58671d3756d5 Mon Sep 17 00:00:00 2001
From: LCJ-MinYa <1049468118@qq.com>
Date: Fri, 26 Dec 2025 15:24:12 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=20=20=20=20=20=20=20=20title:=20'?=
=?UTF-8?q?=E8=A7=A3=E6=9E=84=E8=B5=8B=E5=80=BC=E4=B8=AD=E8=AE=BE=E7=BD=AE?=
=?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=80=BC=E4=B8=8D=E6=88=90=E5=8A=9F=EF=BC=8C?=
=?UTF-8?q?=E5=8E=9F=E5=80=BC=E4=B8=BAnull=E7=9A=84=E9=97=AE=E9=A2=98',=20?=
=?UTF-8?q?=20=20=20=20=20=20=20=20title:=20'=E6=98=8E=E6=98=8E=E7=A8=8B?=
=?UTF-8?q?=E5=BA=8F=E6=8A=A5=E9=94=99=EF=BC=8C=E4=BD=86=E6=98=AF=E6=8E=A7?=
=?UTF-8?q?=E5=88=B6=E5=8F=B0=E4=B8=8D=E6=89=93=E5=8D=B0=E9=94=99=E8=AF=AF?=
=?UTF-8?q?=E7=9A=84=E5=87=A0=E7=A7=8D=E6=83=85=E5=86=B5=EF=BC=88=E5=88=AB?=
=?UTF-8?q?=E6=80=80=E7=96=91=EF=BC=8C=E4=B8=80=E5=AE=9A=E6=98=AF=E4=BB=A3?=
=?UTF-8?q?=E7=A0=81=E9=97=AE=E9=A2=98=EF=BC=8C=E8=80=8C=E4=B8=8D=E6=98=AF?=
=?UTF-8?q?=E7=A8=8B=E5=BA=8F=E8=BF=90=E8=A1=8C=E5=A4=AA=E4=B9=85=EF=BC=89?=
=?UTF-8?q?',?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/router/modules/demo.ts | 8 +
src/views/demo/catchError/catchError.md | 263 ++++++++++++++++++++++++
src/views/demo/catchError/index.vue | 18 ++
src/views/demo/dsAssign/dsAssign.md | 126 ++++++++++++
src/views/demo/dsAssign/index.vue | 18 ++
5 files changed, 433 insertions(+)
create mode 100644 src/views/demo/catchError/catchError.md
create mode 100644 src/views/demo/catchError/index.vue
create mode 100644 src/views/demo/dsAssign/dsAssign.md
create mode 100644 src/views/demo/dsAssign/index.vue
diff --git a/src/router/modules/demo.ts b/src/router/modules/demo.ts
index fd11d8e..b659245 100644
--- a/src/router/modules/demo.ts
+++ b/src/router/modules/demo.ts
@@ -154,6 +154,14 @@ const titleArr = [
key: 'computedWithEnumList',
title: '接口返回数据需要根据多个枚举值动态计算结果渲染(多个枚举值是接口返回,并且不知道具体返回时间)',
},
+ {
+ key: 'dsAssign',
+ title: '解构赋值中设置初始值不成功,原值为null的问题',
+ },
+ {
+ key: 'catchError',
+ title: '明明程序报错,但是控制台不打印错误的几种情况(别怀疑,一定是代码问题,而不是程序运行太久)',
+ },
];
// @/views/demo/**/*.vue
diff --git a/src/views/demo/catchError/catchError.md b/src/views/demo/catchError/catchError.md
new file mode 100644
index 0000000..d75a7ad
--- /dev/null
+++ b/src/views/demo/catchError/catchError.md
@@ -0,0 +1,263 @@
+# 明明程序报错,但是控制台不打印错误的几种情况(别怀疑,一定是代码问题,而不是程序运行太久)
+
+这是一个很常见但容易让人困惑的问题。以下是程序报错但控制台不打印错误的几种常见情况:
+
+## 1. **异步错误未被捕获**
+
+### Promise 错误
+```javascript
+// ❌ 错误不会打印到控制台
+new Promise((resolve, reject) => {
+ throw new Error('Promise error');
+});
+
+// ✅ 需要 catch 处理
+new Promise((resolve, reject) => {
+ throw new Error('Promise error');
+}).catch(error => {
+ console.error('Caught:', error);
+});
+```
+
+### async/await 未捕获
+```javascript
+// ❌ 错误不会打印
+async function test() {
+ throw new Error('Async error');
+}
+test();
+
+// ✅ 需要 try-catch 或外层 catch
+async function test() {
+ throw new Error('Async error');
+}
+test().catch(error => console.error('Caught:', error));
+```
+
+## 2. **setTimeout/setInterval 中的错误**
+```javascript
+// ❌ 错误不会传播到外层
+setTimeout(() => {
+ throw new Error('Timeout error');
+}, 0);
+
+// ✅ 需要在内部 try-catch
+setTimeout(() => {
+ try {
+ throw new Error('Timeout error');
+ } catch (error) {
+ console.error('Caught in timeout:', error);
+ }
+}, 0);
+```
+
+## 3. **事件监听器中的错误**
+```javascript
+// ❌ 错误被事件系统吞掉
+element.addEventListener('click', () => {
+ throw new Error('Event handler error');
+});
+
+// ✅ 需要内部 try-catch
+element.addEventListener('click', () => {
+ try {
+ throw new Error('Event handler error');
+ } catch (error) {
+ console.error('Caught in event:', error);
+ }
+});
+```
+
+## 4. **微任务队列中的错误**
+```javascript
+// ❌ queueMicrotask 中的错误
+queueMicrotask(() => {
+ throw new Error('Microtask error');
+});
+
+// ✅ 需要包装处理
+queueMicrotask(() => {
+ try {
+ throw new Error('Microtask error');
+ } catch (error) {
+ console.error('Caught in microtask:', error);
+ }
+});
+```
+
+## 5. **Web Workers 中的错误**
+```javascript
+// worker.js
+// ❌ 错误不会自动传递到主线程
+throw new Error('Worker error');
+
+// ✅ 需要通过 onerror 或 postMessage
+self.onerror = function(error) {
+ console.error('Worker error:', error);
+ return false; // 返回 false 让错误冒泡到主线程
+};
+```
+
+## 6. **模块加载错误**
+```javascript
+// ❌ ES6 模块中的顶级错误可能被静默处理
+import './module-that-throws.js'; // 模块内部直接 throw
+
+// ✅ 使用动态导入捕获
+import('./module-that-throws.js')
+ .catch(error => console.error('Module load error:', error));
+```
+
+## 7. **被 try-catch 吞掉的错误**
+```javascript
+// ❌ 错误被捕获但没有处理
+try {
+ throw new Error('Some error');
+} catch (error) {
+ // 没有 console.error,错误就消失了
+}
+
+// ❌ 更隐蔽的:catch 块自身出错
+try {
+ throw new Error('First error');
+} catch (error) {
+ console.nonExistentMethod(); // 这个错误不会被捕获!
+}
+```
+
+## 8. **跨域脚本错误**
+```javascript
+// ❌ 跨域脚本的错误信息受限
+
+
+// 浏览器出于安全考虑,只会显示 "Script error."
+```
+
+## 9. **Console 被重写**
+```javascript
+// ❌ 有人重写了 console.error
+const originalError = console.error;
+console.error = () => {}; // 静默所有错误
+
+// 检查 console 是否被篡改
+if (console.error.toString().includes('[native code]')) {
+ console.log('Console is native');
+} else {
+ console.log('Console has been overwritten!');
+}
+```
+
+## 10. **错误在框架中被处理**
+### React 的错误边界
+```jsx
+// ❌ React 16+ 的错误被错误边界捕获
+class ErrorBoundary extends React.Component {
+ componentDidCatch(error, info) {
+ // 如果没有 console.error,错误不会显示
+ // console.error('Error caught by boundary:', error);
+ }
+
+ render() {
+ return this.props.children;
+ }
+}
+```
+
+### Vue 的错误处理
+```javascript
+// ❌ Vue 全局错误处理器
+Vue.config.errorHandler = function (err, vm, info) {
+ // 如果没有处理,错误不会显示
+ // console.error('Vue error:', err);
+};
+```
+
+## 11. **Node.js 特定情况**
+### 未监听的 'error' 事件
+```javascript
+// ❌ EventEmitter 的 error 事件需要监听
+const stream = createReadStream('nonexistent.txt');
+// 如果没有 error 监听器,错误会抛出并崩溃进程
+
+// ✅ 必须监听 error 事件
+stream.on('error', (error) => {
+ console.error('Stream error:', error);
+});
+```
+
+### Domain 模块(已废弃但可能遇到)
+```javascript
+const domain = require('domain');
+const d = domain.create();
+
+// ❌ Domain 可能吞掉错误
+d.on('error', (err) => {
+ // 如果没有处理,错误消失
+});
+
+d.run(() => {
+ throw new Error('Domain error');
+});
+```
+
+## 调试和诊断技巧
+
+### 1. **全局错误监听器**
+```javascript
+// 捕获未处理的 Promise 错误
+window.addEventListener('unhandledrejection', event => {
+ console.error('Unhandled promise rejection:', event.reason);
+ event.preventDefault(); // 阻止默认错误输出
+});
+
+// 捕获全局错误
+window.addEventListener('error', event => {
+ console.error('Global error:', event.error);
+});
+
+// Node.js
+process.on('unhandledRejection', (reason, promise) => {
+ console.error('Unhandled Rejection at:', promise, 'reason:', reason);
+});
+
+process.on('uncaughtException', (error) => {
+ console.error('Uncaught Exception:', error);
+});
+```
+
+### 2. **启用所有错误显示**
+```javascript
+// Chrome DevTools
+// 1. 打开 DevTools → Sources
+// 2. 点击 Pause on exceptions 按钮(⏸️)
+// 3. 勾选 "Pause on caught exceptions"
+
+// Node.js 调试
+node --inspect app.js
+// 或使用 ndb、node --inspect-brk
+```
+
+### 3. **检查控制台过滤器**
+有时控制台过滤器可能被设置为隐藏错误:
+- 检查 Console 顶部的过滤选项
+- 确保 "Errors", "Warnings" 没有被过滤掉
+- 尝试点击 "Default levels" → "All levels"
+
+### 4. **最小化复现**
+```javascript
+// 创建一个最小测试
+console.log('Script is running');
+setTimeout(() => {
+ console.log('About to throw...');
+ throw new Error('Test error');
+}, 1000);
+```
+
+## 总结
+当错误不显示时,通常是因为:
+1. **异步上下文**中的错误
+2. **被某种机制捕获**但未处理
+3. **框架或环境**的特定错误处理
+4. **控制台配置**问题
+
+最好的做法是始终添加全局错误监听器,并在开发时启用"捕获异常时暂停"功能。
\ No newline at end of file
diff --git a/src/views/demo/catchError/index.vue b/src/views/demo/catchError/index.vue
new file mode 100644
index 0000000..e0f5eac
--- /dev/null
+++ b/src/views/demo/catchError/index.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/src/views/demo/dsAssign/dsAssign.md b/src/views/demo/dsAssign/dsAssign.md
new file mode 100644
index 0000000..94f0ba2
--- /dev/null
+++ b/src/views/demo/dsAssign/dsAssign.md
@@ -0,0 +1,126 @@
+# js 解构赋值中设置初始值不成功,原值为null的问题
+在 JavaScript 解构赋值中,当原值为 `null` 时,设置默认值(初始值)可能会失败。这是因为 `null` 被认为是一个有效的值(虽然为空),解构赋值不会将其视为 `undefined`。
+
+## 问题示例
+
+```javascript
+// 正常情况:undefined 会触发默认值
+const obj1 = { a: undefined, b: 2 };
+const { a = 1, b = 1 } = obj1;
+console.log(a); // 1 ✅ 默认值生效
+console.log(b); // 2
+
+// 问题情况:null 不会触发默认值
+const obj2 = { a: null, b: 2 };
+const { a = 1, b = 1 } = obj2;
+console.log(a); // null ❌ 默认值不生效
+console.log(b); // 2
+```
+
+## 解决方案
+
+### 1. **使用逻辑或运算符(||)**
+```javascript
+const obj = { a: null, b: 2 };
+const { a, b } = obj;
+const aWithDefault = a || 1; // 如果 a 是 null、undefined、0、""、false 等,使用默认值
+console.log(aWithDefault); // 1
+```
+
+### 2. **使用空值合并运算符(??)(ES2020)**
+```javascript
+const obj = { a: null, b: 2 };
+const { a, b } = obj;
+const aWithDefault = a ?? 1; // 只在 a 是 null 或 undefined 时使用默认值
+console.log(aWithDefault); // 1
+```
+
+### 3. **解构后处理**
+```javascript
+const obj = { a: null, b: 2 };
+let { a, b } = obj; // !!!!!请注意下面如果要重新设置a的值,必须使用let解构,如果const会报错
+a = a === null ? 1 : a;
+console.log(a); // 1
+```
+
+### 4. **使用函数包装**
+```javascript
+function destructureWithDefaults(obj, defaults) {
+ const result = { ...defaults };
+ for (const key in obj) {
+ if (obj[key] !== undefined) {
+ result[key] = obj[key];
+ }
+ }
+ return result;
+}
+
+const obj = { a: null, b: 2 };
+const { a, b } = destructureWithDefaults(obj, { a: 1, b: 1 });
+console.log(a); // null
+console.log(b); // 2
+```
+
+### 5. **处理嵌套解构**
+```javascript
+const obj = {
+ user: null,
+ settings: { theme: 'dark' }
+};
+
+// 嵌套解构也需要处理 null
+const {
+ user = {}, // 默认值不会生效,因为 user 是 null
+ settings = {}
+} = obj || {}; // 先确保 obj 不是 null
+
+// 更好的方式
+const safeObj = obj || {};
+const safeUser = safeObj.user || {};
+const safeSettings = safeObj.settings || {};
+```
+
+### 6. **自定义解构辅助函数**
+```javascript
+function safeDestructure(obj, defaults) {
+ return Object.keys(defaults).reduce((acc, key) => {
+ const value = obj[key];
+ acc[key] = value === null || value === undefined ? defaults[key] : value;
+ return acc;
+ }, {});
+}
+
+const obj = { a: null, b: 2, c: undefined };
+const { a, b, c } = safeDestructure(obj, { a: 1, b: 1, c: 3, d: 4 });
+console.log(a); // 1
+console.log(b); // 2
+console.log(c); // 3
+```
+
+### 7. **使用 TypeScript(编译时检查)**
+```typescript
+interface MyObject {
+ a: number | null;
+ b: number;
+}
+
+const obj: MyObject = { a: null, b: 2 };
+const { a = 1, b = 1 } = obj; // TypeScript 会警告可能的问题
+// 需要显式处理
+const safeA = a ?? 1;
+```
+
+## 最佳实践建议
+
+1. **了解数据来源**:如果数据可能包含 `null`,提前处理
+2. **使用空值合并运算符(??)**:ES2020+ 环境的最佳选择
+3. **数据清洗**:在解构前将 `null` 转换为 `undefined`
+ ```javascript
+ const cleanObj = Object.fromEntries(
+ Object.entries(obj).map(([k, v]) => [k, v === null ? undefined : v])
+ );
+ const { a = 1 } = cleanObj;
+ ```
+4. **防御性编程**:对可能为 `null` 的层级都进行保护
+
+记住:解构赋值的默认值只在属性值为 `undefined` 时生效,`null` 是一个明确的值,不会触发默认值。
\ No newline at end of file
diff --git a/src/views/demo/dsAssign/index.vue b/src/views/demo/dsAssign/index.vue
new file mode 100644
index 0000000..db485f8
--- /dev/null
+++ b/src/views/demo/dsAssign/index.vue
@@ -0,0 +1,18 @@
+
+
+
+
+