知蛛网
  • 首页
  • 会员
  • 活动
  • 工作台

常见问题
活动
关于我们
联系我们
隐私协议
用户协议
会员协议
© 2026 知蛛网. 保留所有权利。
首页会员工作台我的
flynn@flynn
主页wiki简历作品集
目录
全部书籍
00-路线
  • 学习路线
  • 命名与写作规范
01-计算机基础
01-计算机网络
  • 互联网是如何工作的
  • HTTP协议
  • TCP/IP协议
  • 浏览器直接打开本地html文件,请求时的协议问题
02-浏览器原理
  • 浏览器是如何渲染页面的
  • 浏览器是如何渲染页面的
  • 面试之浏览器
03-操作系统
  • 进程与线程
  • 内存管理与虚拟内存
  • IO 模型与多路复用
  • 文件系统与页缓存
04-数据结构与算法
  • 数组与链表
  • 栈与队列
  • 哈希表
  • 树与堆
  • 基础数据结构
01-基础数据结构
02-高级算法
  • 排序算法
  • 二分查找
  • 递归与回溯
  • 动态规划
  • 双指针与滑动窗口
03-leetcode刷题
02-前端核心
01-web开发
  • Web 和 Web 标准
  • web 入门
  • web 开发
  • URL
  • 域名
  • Web服务器
  • 命令行
  • 工作流程和流程
  • 超链接
  • 浏览器指纹
02-html
  • HTML基础语法
  • HTML 概述
  • HTML 发展史
  • HTML调试
  • HTML标题与段落
  • 文本格式化
  • 强调与重要性
  • 块级元素和内联元素
  • 列表
  • 区块
  • 语义元素
  • 页面结构化和语义化
  • 超链接
  • 相对路径和绝对路径
  • 图片
  • 表格
  • 表单和按钮
  • 多媒体
  • 视频/音频
  • HTML 头部
  • HTML 字符集
  • HTML颜色
  • HTML 语言代码
  • HTML 国家/地区
  • Emoji (表情符号)
  • HTML 标签简写及全称 |
  • SVG
  • Canvas 2D
  • Canvas 3D
  • 框架 `<iframe>`
  • HTML 拖放
  • HTML5 Geolocation(地理定位)
  • Web 存储
  • HTML URL 编码
  • MathML
  • 远程图片资源在自己网站中无法展示问题
03-css
  • CSS简介
  • CSS 语法
  • CSS 创建
  • CSS 发展史
  • CSS 浏览器支持
  • CSS 选择器
  • CSS `!important` 规则
  • css颜色
  • CSS 文本格式
  • CSS 盒子模型
  • CSS 尺寸
  • CSS 内边距
  • CSS 外边距
  • CSS 边框
  • CSS 轮廓
  • CSS 背景(background)
  • CSS 溢出
  • CSS 文档流
  • CSS 显示和可见性
  • CSS 浮动
  • CSS 定位
  • CSS 对齐方式
  • CSS 网页布局
  • CSS 多列布局(CSS Multi-column Layout)
  • CSS 透明度
  • CSS 响应式设计(Responsive Design)
  • CSS 媒体查询
  • CSS 列表
  • CSS 表格
  • CSS 表单
  • CSS 链接
  • CSS 用户界面
  • CSS 计数器
  • CSS 过渡
  • CSS 动画
  • CSS 2D 转换
  • CSS 3D 转换
  • CSS 变量(CSS Custom Properties)
  • CSS 原生嵌套(CSS Nesting)
  • CSS 函数(CSS Functions)
04-javascript
  • 什么是 JavaScript?
  • 编程范式(Programming Paradigm)
  • 什么是范式?
  • ECMAScript 规范
  • 什么是语法糖
  • 开发环境搭建
  • 什么是堆和栈?
  • 什么是执行上下文
  • JavaScript 垃圾回收机制
  • 作业队列与事件循环
  • 深拷贝和浅拷贝
  • 语法与类型
  • 字面量
  • 控制流与错误处理
  • 循环与迭代
  • 函数
  • 表达式与运算符
  • 数字和字符串
  • 表达日期与时间
  • 正则表达式
  • 索引集合类
  • 带键的集合
  • 对象
  • 类
  • Promise
  • async/await
  • 迭代器和生成器
  • 国际化
  • 模块
  • 资源管理
  • 属性的可枚举性和所有权
  • 闭包
  • 继承与原型链
  • 元编程
  • 内存管理
  • 内置对象
  • arguments 对象
  • BOM 对象(浏览器对象模型)
  • DOM 对象(文档对象模型)
  • bind、apply、call的区别
  • new 操作符
  • typeof 和 instanceof 的区别
  • HTML5 Web Workers
05-typescript
  • TypeScript 类型系统基础
  • 类型体操
03-框架与跨端
01-react
  • 开发环境搭建
  • JSX
  • 组件
  • 生命周期
  • Hooks
  • 组件通信
  • 状态管理
  • React 19 新特性
  • useCallback 闭包陷阱
  • 常用的性能优化操作
  • Firbe 架构
  • React 18 新特性
  • useRef
  • 基于umijs 4.0 搭建官网
  • react+vite本地开发,如何手机联调
  • React 实现谷歌登录
  • React 项目调起 WhatsApp
02-vue
  • vue 解决跨域请求
  • 在vue2使用TinyMCE富文本编辑器
  • 使用jszip 导出新闻
  • Vue 本地开发启用 https
  • 基于vue3+vite+ts+elementplus+pinia+axios搭建后台管理系统
03-react-native
  • iOS 开发环境(RN 0.72)
  • RN 原生模块(Native Module)
  • 查看Maven包的Java包名
  • 优化 APP 启动速度
  • 安全键盘
  • 启动图与 Icon 尺寸规范
  • RN如何生成/配置iOS的开发者证书和生产证书
  • 邓白氏编码
  • 微信开放平台配置Universal Link
  • 上架至Apple App Store
04-android
  • 开发环境搭建
  • Android项目目录结构
  • 认识Gradle
04-工程化
01-git
  • 如何解决已被git跟踪文件不在跟踪
  • git标签
  • Git报错: Failed to connect to github.com port 443 解决方案
  • Git 分支操作速查
02-构建工具
  • 构建工具原理与选型
02-webpack
  • webpack 核心概念与构建流程
  • webpack 性能优化
03-vite
  • vite 为什么快
  • vite 插件与生产构建
03-测试
  • 前端测试体系
04-部署
  • Nginx 反向代理解决跨域
  • SPA 刷新非首页报 404
05-docker
  • Docker 常用命令
  • docker-compose nginx配置ssl证书
  • Docker Desktop 升级后 docker-compose 命令找不到
06-性能优化
  • 前端性能优化体系
  • 背景 GIF 优化方案
07-微前端
  • 微前端实战(qiankun)
  • 微前端 · qiankun
01-qiankun
05-后端与数据
01-nodejs
  • Node 版本与依赖的 engines 冲突
  • Express 实现 Gmail 发信(邮箱验证码)
02-php
  • 浏览器保存新闻,发布到自有网站
  • [分布式] 浏览器保存新闻,发布到自有网站
  • 邮件发送,多账号轮询
  • nginx和php-fpm通信问题导致网站页面空白
03-python
  • macOS M1 芯片 如何安装 py 和 tkinter
  • tkinter 编写的程序如何打包成桌面软件
04-架构设计
  • 后台管理系统中角色管理、管理员管理、权限设置他们三者之间的关系
05-运维
  • redis启动失败
  • 实现自动备份宝塔项目及数据库到本地
  • 宝塔面板
01-宝塔
06-实战项目
  • 实战准备工作
02-项目记录
  • AI-Chat 模块技术文档
  • CRMChat 部署
07-面试专项
01-面试
  • 面试之自我介绍
  • CSS 面试
  • JS面试
  • React面试
  • Vue面试
  • RN 面试 · 题目清单
  • RN 面试 · 答案详解
  • RN 物流公司 · 题目清单
  • RN 物流公司 · 答案详解
  • Uniapp 面试
  • 带团队经验
12-react专项
  • 一个表格,某一行的某一列数据变动了,如何优化性能?
13-reactnative专项
  • RN 开发过程中,有遇到什么棘手的问题?你是如何解决的?
14-过往面试总结
  • 冷哥传媒 · 面试题
  • 沐腾科技 · 面试题
  • 字符频率排序
02-面试八股
  • 网络八股
  • 浏览器八股
  • 工程化八股
03-算法面试题
  • 前端高频手写题
  • 场景设计题
04-真实面试经历
  • 20251027 盾蓝科技 面试
  • 20251028 芝麻甜心 面试
08-工具
01-n8n
  • 初始n8n
  • 快速入门
  • 在宝塔中搭建n8n环境
  • n8n中常用节点
  • n8n和代码的区别
02-Trae
  • Figma MCP 配置指南
03-UI_UX_pro_max
  • UI_UX_pro_max的使用
04-开发环境
  • VMWare虚拟机安装
  • PowerShell 执行策略与编码设置
98-杂项
  • A股股票交易相关费用
99-手册
  • iOS 开发者账号申请流程及费用
  • 邓白氏编码申请及费用
  • App 推送通道申请及费用
  • App 开发收费项目清单
  • 注册AWS账号
  • 使用Amazon Polly实现文本转语音
  • Google 翻译 Key 申请与前端调用
  • 使用SmsForwarder转发短信

控制流与错误处理

04-javascript2026/11/14

控制流语句

1. 条件语句

if...else

// 基本形式
if (condition) {
    // 条件为真时执行
} else if (anotherCondition) {
    // 另一个条件为真时执行
} else {
    // 以上条件都不为真时执行
}

// 示例
let score = 85;

if (score >= 90) {
    console.log("优秀");
} else if (score >= 80) {
    console.log("良好");
} else if (score >= 60) {
    console.log("及格");
} else {
    console.log("不及格");
}

// 三元运算符
let result = score >= 60 ? "及格" : "不及格";
let grade = score >= 90 ? "A" : score >= 80 ? "B" : "C";

switch

switch (expression) {
    case value1:
        // 匹配 value1 时执行
        break;
    case value2:
        // 匹配 value2 时执行
        break;
    default:
    // 没有匹配时执行
}

// 示例
let day = 3;
let dayName;

switch (day) {
    case 1:
        dayName = "星期一";
        break;
    case 2:
        dayName = "星期二";
        break;
    case 3:
        dayName = "星期三";
        break;
    case 4:
        dayName = "星期四";
        break;
    case 5:
        dayName = "星期五";
        break;
    case 6:
        dayName = "星期六";
        break;
    case 7:
        dayName = "星期日";
        break;
    default:
        dayName = "无效的日期";
}

// 多个 case 共享代码
let month = 2;
let season;

switch (month) {
    case 12:
    case 1:
    case 2:
        season = "冬季";
        break;
    case 3:
    case 4:
    case 5:
        season = "春季";
        break;
    case 6:
    case 7:
    case 8:
        season = "夏季";
        break;
    case 9:
    case 10:
    case 11:
        season = "秋季";
        break;
    default:
        season = "无效的月份";
}

错误处理

1. try...catch...finally

// 基本语法
try {
    // 可能会抛出错误的代码
    riskyOperation();
} catch (error) {
    // 错误处理
    console.error("发生错误:", error.message);
} finally {
    // 无论是否发生错误都会执行
    console.log("清理操作");
}

// 示例
function divide(a, b) {
    try {
        if (b === 0) {
            throw new Error("除数不能为零");
        }
        return a / b;
    } catch (error) {
        console.error("计算错误:", error.message);
        return NaN;
    } finally {
        console.log("除法运算完成");
    }
}

// 多个 catch 块(ES2019+)
try {
    // 可能抛出多种类型的错误
} catch (error) {
    if (error instanceof TypeError) {
        // 处理类型错误
    } else if (error instanceof RangeError) {
        // 处理范围错误
    } else if (error instanceof EvalError) {
        // 处理 eval 错误
    } else {
        // 处理其他错误
    }
}

2. Error 类型

// 内置 Error 类型
try {
    throw new Error("普通错误");
} catch (e) {
    console.log(e.name); // "Error"
    console.log(e.message); // "普通错误"
    console.log(e.stack); // 堆栈跟踪
}

// 特定错误类型
try {
    throw new SyntaxError("语法错误");
    throw new TypeError("类型错误");
    throw new RangeError("范围错误");
    throw new ReferenceError("引用错误");
    throw new URIError("URI错误");
    throw new EvalError("Eval错误");
} catch (error) {
    console.error(error.name + ": " + error.message);
}

// 自定义错误
class ValidationError extends Error {
    constructor(message, field) {
        super(message);
        this.name = "ValidationError";
        this.field = field;
        this.timestamp = new Date().toISOString();
    }
}

try {
    throw new ValidationError("无效的输入", "username");
} catch (error) {
    if (error instanceof ValidationError) {
        console.error(`${error.name}: ${error.message} (字段: ${error.field})`);
    }
}
上一篇字面量
下一篇循环与迭代
本页目录
控制流语句1. 条件语句错误处理1. `try...catch...finally`2. Error 类型3. `throw` 语句高级控制流模式1. 短路求值2. 条件链式调用3. 使用函数式方法4. 生成器和迭代器错误处理最佳实践1. 防御性编程2. 异步错误处理3. 全局错误处理4. 错误恢复策略调试技巧1. 控制台方法2. debugger 语句代码质量工具1. ESLint 规则

3. throw 语句

// 抛出字符串(不推荐)
throw "发生错误";

// 抛出数字(不推荐)
throw 404;

// 抛出对象(不推荐)
throw { message: "错误", code: 500 };

// 抛出 Error 对象(推荐)
throw new Error("错误描述");

// 条件抛出
function getUser(id) {
    if (!id || id <= 0) {
        throw new Error("无效的用户ID");
    }
    // 获取用户逻辑...
}

// 在表达式中使用 throw
function getDefault(value) {
    return value || throw new Error("值不能为空");
}

高级控制流模式

1. 短路求值

// 逻辑与 (&&) 短路
let user = null;
let username = user && user.name; // 不会报错,返回 null

// 逻辑或 (||) 短路
let config = userConfig || defaultConfig;

// 空值合并运算符 ?? (ES2020)
let value = null ?? "default"; // "default"
let value2 = 0 ?? "default"; // 0 (与 || 不同)

// 可选链操作符 ?. (ES2020)
let street = user?.address?.street; // 不会报错

2. 条件链式调用

// 传统方式
let result;
if (obj) {
    if (obj.method1) {
        result = obj.method1();
        if (result && result.method2) {
            return result.method2();
        }
    }
}

// 链式调用
let result = obj?.method1?.()?.method2?.();

3. 使用函数式方法

// 替代 for 循环
const numbers = [1, 2, 3, 4, 5];

// 遍历
numbers.forEach(num => console.log(num));

// 过滤
const even = numbers.filter(num => num % 2 === 0);

// 映射
const doubled = numbers.map(num => num * 2);

// 查找
const firstEven = numbers.find(num => num % 2 === 0);

// 检查
const allPositive = numbers.every(num => num > 0);
const hasNegative = numbers.some(num => num < 0);

// 归约
const sum = numbers.reduce((total, num) => total + num, 0);

4. 生成器和迭代器

// 生成器函数
function* numberGenerator() {
    let num = 1;
    while (true) {
        yield num++;
    }
}

const gen = numberGenerator();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2

// 使用生成器控制流程
function* taskRunner() {
    console.log("开始任务1");
    yield;
    console.log("开始任务2");
    yield;
    console.log("所有任务完成");
}

const runner = taskRunner();
runner.next(); // 开始任务1
runner.next(); // 开始任务2
runner.next(); // 所有任务完成

错误处理最佳实践

1. 防御性编程

// 参数验证
function processData(data) {
    if (!data || typeof data !== "object") {
        throw new TypeError("参数必须是对象");
    }

    if (!Array.isArray(data.items)) {
        throw new TypeError("items 必须是数组");
    }

    // 安全地处理数据
    return data.items.map(item => ({
        ...item,
        processed: true,
    }));
}

// 使用默认值
function createUser(options = {}) {
    const defaults = {
        name: "匿名",
        age: 18,
        email: "",
    };

    return { ...defaults, ...options };
}

2. 异步错误处理

// Promise 错误处理
fetch("https://api.example.com/data")
    .then(response => {
        if (!response.ok) {
            throw new Error(`HTTP错误: ${response.status}`);
        }
        return response.json();
    })
    .then(data => console.log(data))
    .catch(error => console.error("请求失败:", error));

// async/await 错误处理
async function fetchData() {
    try {
        const response = await fetch("https://api.example.com/data");
        if (!response.ok) {
            throw new Error(`HTTP错误: ${response.status}`);
        }
        const data = await response.json();
        return data;
    } catch (error) {
        console.error("获取数据失败:", error);
        // 返回默认值或重新抛出
        throw error; // 或 return defaultValue;
    }
}

// 并行异步错误处理
async function fetchMultiple() {
    try {
        const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);
        return { data1, data2 };
    } catch (error) {
        // 处理第一个失败的情况
        console.error("并行请求失败:", error);
    }
}

3. 全局错误处理

// 全局错误事件
window.addEventListener("error", function (event) {
    console.error("全局错误:", event.error);
    // 发送到错误监控服务
    sendToErrorTracking(event.error);
    // 阻止默认错误处理
    event.preventDefault();
});

// 未处理的 Promise 拒绝
window.addEventListener("unhandledrejection", function (event) {
    console.error("未处理的 Promise 拒绝:", event.reason);
    event.preventDefault();
});

// Node.js 全局错误处理
process.on("uncaughtException", error => {
    console.error("未捕获的异常:", error);
    // 记录错误并优雅退出
    process.exit(1);
});

process.on("unhandledRejection", (reason, promise) => {
    console.error("未处理的 Promise 拒绝:", reason);
});

4. 错误恢复策略

// 重试机制
async function fetchWithRetry(url, maxRetries = 3) {
    for (let i = 0; i <= maxRetries; i++) {
        try {
            const response = await fetch(url);
            return await response.json();
        } catch (error) {
            if (i === maxRetries) {
                throw error;
            }
            console.log(`重试 ${i + 1}/${maxRetries}`);
            await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, i))); // 指数退避
        }
    }
}

// 降级策略
async function getData() {
    try {
        return await fetchFromPrimarySource();
    } catch (error) {
        console.warn("主数据源失败,使用备用源");
        try {
            return await fetchFromFallbackSource();
        } catch (fallbackError) {
            console.error("所有数据源都失败");
            return getCachedData(); // 返回缓存数据
        }
    }
}

调试技巧

1. 控制台方法

// 不同级别的日志
console.log("普通日志");
console.info("信息日志");
console.warn("警告日志");
console.error("错误日志");
console.debug("调试日志");

// 分组日志
console.group("用户信息");
console.log("姓名: 张三");
console.log("年龄: 25");
console.groupEnd();

// 表格显示
console.table([
    { name: "张三", age: 25 },
    { name: "李四", age: 30 },
]);

// 断言
console.assert(1 === 2, "1 不等于 2");

// 跟踪调用栈
console.trace("当前位置");

// 性能测量
console.time("操作耗时");
// 执行操作...
console.timeEnd("操作耗时");

2. debugger 语句

function complexOperation() {
    let result = 0;
    debugger; // 执行到这里会暂停,可以检查变量

    for (let i = 0; i < 10; i++) {
        result += i;
    }

    return result;
}

代码质量工具

1. ESLint 规则

// .eslintrc.js 中的控制流相关规则
module.exports = {
    rules: {
        "no-constant-condition": "error", // 禁止常量条件
        "no-unreachable": "error", // 禁止不可达代码
        "no-duplicate-case": "error", // 禁止重复 case
        "default-case": "warn", // 要求 switch 有 default
        "no-fallthrough": "error", // 禁止 case 穿透
        "no-labels": "warn", // 避免使用标签
        "no-unused-expressions": "error", // 禁止未使用的表达式
        "no-console": "warn", // 避免使用 console
        "consistent-return": "error", // 要求一致的返回值
        curly: ["error", "all"], // 要求使用大括号
        eqeqeq: ["error", "always"], // 要求使用 === 和 !==
        "no-throw-literal": "error", // 只能抛出 Error 对象
        "no-unsafe-finally": "error", // finally 中避免控制转移
    },
};