条件语句

if语句

// 基本if语句
let age = 18;
if (age >= 18) {
  console.log('成年人');
}

// if-else语句
let score = 85;
if (score >= 90) {
  console.log('优秀');
} else {
  console.log('良好');
}

// if-else if-else语句
let temperature = 25;
if (temperature > 30) {
  console.log('炎热');
} else if (temperature > 20) {
  console.log('温暖');
} else if (temperature > 10) {
  console.log('凉爽');
} else {
  console.log('寒冷');
}

// 嵌套if语句
let weather = 'sunny';
let temperature2 = 28;
if (weather === 'sunny') {
  if (temperature2 > 25) {
    console.log('适合游泳');
  } else {
    console.log('适合散步');
  }
} else {
  console.log('待在室内');
}

// 条件表达式中的类型转换
let value = 0;
if (value) {
  console.log('真值'); // 不会执行
} else {
  console.log('假值'); // 会执行
}

// 使用逻辑运算符简化条件
let user = { name: 'Alice', isAdmin: true };

// 传统写法
if (user && user.isAdmin) {
  console.log('管理员用户');
}

// 使用可选链(ES2020)
if (user?.isAdmin) {
  console.log('管理员用户');
}

// 短路求值
user && user.isAdmin && console.log('管理员用户');

// 三元运算符
let status = age >= 18 ? '成年' : '未成年';
let message = user?.name ? `欢迎,${user.name}` : '请登录';

// 复杂的三元运算符
let grade = score >= 90 ? 'A' : score >= 80 ? 'B' : score >= 70 ? 'C' : 'D';

switch语句

// 基本switch语句
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:
  case 7:
    dayName = '周末';
    break;
  default:
    dayName = '无效日期';
}

console.log(dayName); // '星期三'

// 没有break的情况(fall-through)
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 = '无效月份';
}

// switch中使用表达式
let operation = '+';
let a = 10;
let b = 5;
let result;

switch (operation) {
  case '+':
    result = a + b;
    break;
  case '-':
    result = a - b;
    break;
  case '*':
    result = a * b;
    break;
  case '/':
    result = b !== 0 ? a / b : 'Error: Division by zero';
    break;
  default:
    result = 'Error: Invalid operation';
}

// 使用函数替代复杂的switch
function getSeasonByMonth(month) {
  const seasons = {
    12: '冬季', 1: '冬季', 2: '冬季',
    3: '春季', 4: '春季', 5: '春季',
    6: '夏季', 7: '夏季', 8: '夏季',
    9: '秋季', 10: '秋季', 11: '秋季'
  };
  return seasons[month] || '无效月份';
}

// 使用Map替代switch
const operationMap = new Map([
  ['+', (a, b) => a + b],
  ['-', (a, b) => a - b],
  ['*', (a, b) => a * b],
  ['/', (a, b) => b !== 0 ? a / b : 'Error: Division by zero']
]);

function calculate(operation, a, b) {
  const fn = operationMap.get(operation);
  return fn ? fn(a, b) : 'Error: Invalid operation';
}

循环语句

for循环

// 基本for循环
for (let i = 0; i < 5; i++) {
  console.log(`循环第 ${i + 1} 次`);
}

// 倒序循环
for (let i = 5; i > 0; i--) {
  console.log(`倒数第 ${6 - i} 次`);
}

// 步长不为1的循环
for (let i = 0; i < 20; i += 3) {
  console.log(i); // 0, 3, 6, 9, 12, 15, 18
}

// 多变量循环
for (let i = 0, j = 10; i < 5; i++, j--) {
  console.log(`i: ${i}, j: ${j}`);
}

// 无限循环(需要break跳出)
for (;;) {
  let input = Math.random();
  if (input > 0.9) {
    console.log('找到大于0.9的随机数:', input);
    break;
  }
}

// 嵌套for循环
for (let i = 1; i <= 3; i++) {
  for (let j = 1; j <= 3; j++) {
    console.log(`${i} x ${j} = ${i * j}`);
  }
}

// 使用for循环处理数组
let numbers = [1, 2, 3, 4, 5];
let sum = 0;

for (let i = 0; i < numbers.length; i++) {
  sum += numbers[i];
}
console.log('数组总和:', sum);

// 查找数组中的元素
let fruits = ['apple', 'banana', 'orange', 'grape'];
let target = 'orange';
let found = false;

for (let i = 0; i < fruits.length; i++) {
  if (fruits[i] === target) {
    console.log(`找到 ${target} 在索引 ${i}`);
    found = true;
    break;
  }
}

if (!found) {
  console.log(`未找到 ${target}`);
}

for…in循环

// 遍历对象属性
let person = {
  name: 'Alice',
  age: 30,
  city: 'New York',
  occupation: 'Developer'
};

for (let key in person) {
  console.log(`${key}: ${person[key]}`);
}

// 遍历数组索引(不推荐)
let colors = ['red', 'green', 'blue'];
for (let index in colors) {
  console.log(`索引 ${index}: ${colors[index]}`);
}

// 注意:for...in会遍历继承的属性
function Animal(name) {
  this.name = name;
}
Animal.prototype.species = 'Unknown';

let dog = new Animal('Buddy');
dog.breed = 'Golden Retriever';

console.log('使用for...in:');
for (let prop in dog) {
  console.log(`${prop}: ${dog[prop]}`);
  // 输出: name, breed, species
}

console.log('只遍历自有属性:');
for (let prop in dog) {
  if (dog.hasOwnProperty(prop)) {
    console.log(`${prop}: ${dog[prop]}`);
    // 输出: name, breed
  }
}

// 使用Object.keys()替代for...in
console.log('使用Object.keys():');
Object.keys(dog).forEach(prop => {
  console.log(`${prop}: ${dog[prop]}`);
});

for…of循环

// 遍历数组元素
let numbers = [1, 2, 3, 4, 5];
for (let num of numbers) {
  console.log(num);
}

// 遍历字符串字符
let text = 'Hello';
for (let char of text) {
  console.log(char);
}

// 遍历Set
let uniqueNumbers = new Set([1, 2, 3, 2, 1]);
for (let num of uniqueNumbers) {
  console.log(num); // 1, 2, 3
}

// 遍历Map
let userRoles = new Map([
  ['alice', 'admin'],
  ['bob', 'user'],
  ['charlie', 'moderator']
]);

for (let [username, role] of userRoles) {
  console.log(`${username}: ${role}`);
}

// 遍历Map的键或值
for (let username of userRoles.keys()) {
  console.log('用户:', username);
}

for (let role of userRoles.values()) {
  console.log('角色:', role);
}

// 遍历函数参数(arguments对象)
function showArguments() {
  for (let arg of arguments) {
    console.log(arg);
  }
}
showArguments('a', 'b', 'c');

// 遍历NodeList(DOM元素列表)
// const divs = document.querySelectorAll('div');
// for (let div of divs) {
//   console.log(div.textContent);
// }

// 获取数组索引和值
let fruits = ['apple', 'banana', 'orange'];
for (let [index, fruit] of fruits.entries()) {
  console.log(`${index}: ${fruit}`);
}

// 自定义可迭代对象
let range = {
  start: 1,
  end: 5,
  [Symbol.iterator]() {
    let current = this.start;
    let end = this.end;
    return {
      next() {
        if (current <= end) {
          return { value: current++, done: false };
        } else {
          return { done: true };
        }
      }
    };
  }
};

for (let num of range) {
  console.log(num); // 1, 2, 3, 4, 5
}

while循环

// 基本while循环
let count = 0;
while (count < 5) {
  console.log(`计数: ${count}`);
  count++;
}

// 条件在循环体内改变
let randomNum;
while ((randomNum = Math.random()) < 0.9) {
  console.log('随机数:', randomNum);
}
console.log('找到大于0.9的数:', randomNum);

// 使用while循环处理用户输入(模拟)
let userInput = '';
let attempts = 0;
const maxAttempts = 3;

while (userInput !== 'quit' && attempts < maxAttempts) {
  // 模拟用户输入
  userInput = ['hello', 'world', 'quit'][attempts];
  console.log(`用户输入: ${userInput}`);
  attempts++;
  
  if (userInput === 'quit') {
    console.log('用户选择退出');
  } else if (attempts >= maxAttempts) {
    console.log('达到最大尝试次数');
  }
}

// 使用while循环遍历链表(模拟)
class ListNode {
  constructor(value, next = null) {
    this.value = value;
    this.next = next;
  }
}

// 创建链表: 1 -> 2 -> 3 -> null
let head = new ListNode(1, new ListNode(2, new ListNode(3)));

// 遍历链表
let current = head;
while (current !== null) {
  console.log('节点值:', current.value);
  current = current.next;
}

// 无限循环的危险示例(注释掉避免执行)
// let x = 1;
// while (x > 0) {
//   x++; // x永远大于0,造成无限循环
// }

do…while循环

// 基本do...while循环
let i = 0;
do {
  console.log(`执行第 ${i + 1} 次`);
  i++;
} while (i < 3);

// 至少执行一次的特性
let condition = false;
do {
  console.log('这行代码会执行一次,即使条件为false');
} while (condition);

// 菜单系统示例
function showMenu() {
  let choice;
  do {
    console.log('\n=== 菜单 ===');
    console.log('1. 选项一');
    console.log('2. 选项二');
    console.log('3. 选项三');
    console.log('0. 退出');
    
    // 模拟用户选择
    choice = Math.floor(Math.random() * 4);
    console.log(`用户选择: ${choice}`);
    
    switch (choice) {
      case 1:
        console.log('执行选项一');
        break;
      case 2:
        console.log('执行选项二');
        break;
      case 3:
        console.log('执行选项三');
        break;
      case 0:
        console.log('退出程序');
        break;
      default:
        console.log('无效选择,请重新选择');
    }
  } while (choice !== 0);
}

// showMenu(); // 取消注释以运行

// 输入验证示例
function validateInput() {
  let input;
  let isValid;
  
  do {
    // 模拟用户输入
    input = ['', 'abc', '123', 'valid'][Math.floor(Math.random() * 4)];
    console.log(`输入: "${input}"`);
    
    isValid = input.length > 0 && input !== 'abc';
    
    if (!isValid) {
      console.log('输入无效,请重新输入');
    }
  } while (!isValid);
  
  console.log('输入有效:', input);
  return input;
}

// validateInput(); // 取消注释以运行

跳转语句

break语句

// 在循环中使用break
for (let i = 0; i < 10; i++) {
  if (i === 5) {
    console.log('遇到5,跳出循环');
    break;
  }
  console.log(i); // 输出: 0, 1, 2, 3, 4
}

// 在嵌套循环中使用break
console.log('\n嵌套循环中的break:');
for (let i = 0; i < 3; i++) {
  console.log(`外层循环 i = ${i}`);
  for (let j = 0; j < 3; j++) {
    if (j === 1) {
      console.log('  内层循环遇到j=1,跳出内层循环');
      break; // 只跳出内层循环
    }
    console.log(`  内层循环 j = ${j}`);
  }
}

// 使用标签跳出外层循环
console.log('\n使用标签跳出外层循环:');
outer: for (let i = 0; i < 3; i++) {
  console.log(`外层循环 i = ${i}`);
  for (let j = 0; j < 3; j++) {
    if (i === 1 && j === 1) {
      console.log('  跳出外层循环');
      break outer; // 跳出标记为outer的循环
    }
    console.log(`  内层循环 j = ${j}`);
  }
}

// 在while循环中使用break
let count = 0;
while (true) { // 无限循环
  count++;
  console.log(`计数: ${count}`);
  
  if (count >= 3) {
    console.log('达到计数限制,跳出循环');
    break;
  }
}

// 在switch语句中使用break
let grade = 'B';
switch (grade) {
  case 'A':
    console.log('优秀');
    break;
  case 'B':
    console.log('良好');
    break; // 防止fall-through
  case 'C':
    console.log('及格');
    break;
  default:
    console.log('不及格');
}

continue语句

// 在for循环中使用continue
console.log('跳过偶数:');
for (let i = 1; i <= 10; i++) {
  if (i % 2 === 0) {
    continue; // 跳过偶数
  }
  console.log(i); // 输出: 1, 3, 5, 7, 9
}

// 处理数组时跳过某些元素
let numbers = [1, -2, 3, -4, 5, -6, 7];
console.log('\n只处理正数:');
for (let i = 0; i < numbers.length; i++) {
  if (numbers[i] < 0) {
    continue; // 跳过负数
  }
  console.log(`正数: ${numbers[i]}`);
}

// 在嵌套循环中使用continue
console.log('\n嵌套循环中的continue:');
for (let i = 1; i <= 3; i++) {
  console.log(`外层循环 i = ${i}`);
  for (let j = 1; j <= 3; j++) {
    if (j === 2) {
      console.log('  跳过 j = 2');
      continue; // 跳过当前内层循环迭代
    }
    console.log(`  内层循环 j = ${j}`);
  }
}

// 使用标签和continue
console.log('\n使用标签的continue:');
outer: for (let i = 1; i <= 3; i++) {
  console.log(`外层循环 i = ${i}`);
  for (let j = 1; j <= 3; j++) {
    if (i === 2 && j === 1) {
      console.log('  跳过外层循环的当前迭代');
      continue outer; // 跳过外层循环的当前迭代
    }
    console.log(`  内层循环 j = ${j}`);
  }
}

// 在while循环中使用continue
let num = 0;
console.log('\nwhile循环中跳过5的倍数:');
while (num < 10) {
  num++;
  if (num % 5 === 0) {
    continue; // 跳过5的倍数
  }
  console.log(num); // 输出: 1, 2, 3, 4, 6, 7, 8, 9
}

// 实际应用:过滤和处理数据
let users = [
  { name: 'Alice', age: 25, active: true },
  { name: 'Bob', age: 17, active: false },
  { name: 'Charlie', age: 30, active: true },
  { name: 'David', age: 16, active: true }
];

console.log('\n处理活跃的成年用户:');
for (let i = 0; i < users.length; i++) {
  let user = users[i];
  
  // 跳过未成年用户
  if (user.age < 18) {
    console.log(`跳过未成年用户: ${user.name}`);
    continue;
  }
  
  // 跳过非活跃用户
  if (!user.active) {
    console.log(`跳过非活跃用户: ${user.name}`);
    continue;
  }
  
  // 处理符合条件的用户
  console.log(`处理用户: ${user.name}, 年龄: ${user.age}`);
}

return语句

// 基本return语句
function add(a, b) {
  return a + b; // 返回计算结果
}

let result = add(3, 5);
console.log('加法结果:', result); // 8

// 提前返回(早期返回)
function checkAge(age) {
  if (age < 0) {
    return '年龄不能为负数'; // 提前返回
  }
  
  if (age < 18) {
    return '未成年';
  }
  
  if (age >= 65) {
    return '老年人';
  }
  
  return '成年人';
}

console.log(checkAge(-5));  // '年龄不能为负数'
console.log(checkAge(16));  // '未成年'
console.log(checkAge(25));  // '成年人'
console.log(checkAge(70));  // '老年人'

// 没有返回值的函数
function greet(name) {
  console.log(`Hello, ${name}!`);
  // 隐式返回undefined
}

let greeting = greet('Alice'); // 输出: Hello, Alice!
console.log('返回值:', greeting); // undefined

// 显式返回undefined
function doSomething() {
  console.log('执行某些操作...');
  return; // 显式返回undefined
}

// 在循环中使用return
function findFirstEven(numbers) {
  for (let i = 0; i < numbers.length; i++) {
    if (numbers[i] % 2 === 0) {
      return numbers[i]; // 找到第一个偶数就返回
    }
  }
  return null; // 没找到偶数
}

let nums = [1, 3, 7, 8, 9, 12];
console.log('第一个偶数:', findFirstEven(nums)); // 8

// 返回对象
function createUser(name, age) {
  return {
    name: name,
    age: age,
    greet() {
      return `Hi, I'm ${this.name}`;
    }
  };
}

let user = createUser('Bob', 30);
console.log(user.greet()); // Hi, I'm Bob

// 返回函数(高阶函数)
function createMultiplier(factor) {
  return function(number) {
    return number * factor;
  };
}

let double = createMultiplier(2);
let triple = createMultiplier(3);

console.log(double(5)); // 10
console.log(triple(4)); // 12

// 箭头函数的隐式返回
const square = x => x * x; // 隐式返回x * x
const isEven = n => n % 2 === 0; // 隐式返回布尔值

// 箭头函数返回对象需要括号
const createPoint = (x, y) => ({ x: x, y: y });

console.log(square(4));        // 16
console.log(isEven(7));        // false
console.log(createPoint(3, 4)); // { x: 3, y: 4 }

异常处理

try…catch语句

// 基本try...catch
try {
  let result = 10 / 0;
  console.log('结果:', result); // Infinity(不会抛出错误)
  
  // 手动抛出错误
  if (result === Infinity) {
    throw new Error('除零错误');
  }
} catch (error) {
  console.log('捕获到错误:', error.message);
}

// 处理JSON解析错误
function parseJSON(jsonString) {
  try {
    let data = JSON.parse(jsonString);
    console.log('解析成功:', data);
    return data;
  } catch (error) {
    console.log('JSON解析失败:', error.message);
    return null;
  }
}

parseJSON('{"name": "Alice"}'); // 成功
parseJSON('{name: "Alice"}');   // 失败,无效JSON

// 捕获不同类型的错误
function processData(data) {
  try {
    if (typeof data !== 'object') {
      throw new TypeError('数据必须是对象');
    }
    
    if (!data.hasOwnProperty('id')) {
      throw new ReferenceError('缺少id属性');
    }
    
    if (data.id < 0) {
      throw new RangeError('id不能为负数');
    }
    
    console.log('数据处理成功:', data);
  } catch (error) {
    if (error instanceof TypeError) {
      console.log('类型错误:', error.message);
    } else if (error instanceof ReferenceError) {
      console.log('引用错误:', error.message);
    } else if (error instanceof RangeError) {
      console.log('范围错误:', error.message);
    } else {
      console.log('未知错误:', error.message);
    }
  }
}

processData('not an object');     // 类型错误
processData({});                  // 引用错误
processData({ id: -1 });          // 范围错误
processData({ id: 1, name: 'test' }); // 成功

try…catch…finally

// 使用finally块
function readFile(filename) {
  let file = null;
  
  try {
    console.log(`尝试打开文件: ${filename}`);
    
    if (filename === 'nonexistent.txt') {
      throw new Error('文件不存在');
    }
    
    file = { name: filename, content: '文件内容' };
    console.log('文件读取成功');
    return file.content;
    
  } catch (error) {
    console.log('文件读取失败:', error.message);
    return null;
    
  } finally {
    // 无论成功还是失败都会执行
    if (file) {
      console.log('关闭文件');
    }
    console.log('清理资源');
  }
}

console.log('\n读取存在的文件:');
readFile('data.txt');

console.log('\n读取不存在的文件:');
readFile('nonexistent.txt');

// finally中的return会覆盖try/catch中的return
function testFinally() {
  try {
    return 'try';
  } catch (error) {
    return 'catch';
  } finally {
    console.log('finally执行');
    // return 'finally'; // 如果取消注释,会覆盖try中的返回值
  }
}

console.log('\ntestFinally结果:', testFinally());

// 嵌套try...catch
function nestedTryCatch() {
  try {
    console.log('外层try开始');
    
    try {
      console.log('内层try开始');
      throw new Error('内层错误');
    } catch (innerError) {
      console.log('内层catch:', innerError.message);
      throw new Error('重新抛出错误');
    } finally {
      console.log('内层finally');
    }
    
  } catch (outerError) {
    console.log('外层catch:', outerError.message);
  } finally {
    console.log('外层finally');
  }
}

console.log('\n嵌套try...catch:');
nestedTryCatch();

自定义错误类型

// 自定义错误类
class ValidationError extends Error {
  constructor(message, field) {
    super(message);
    this.name = 'ValidationError';
    this.field = field;
  }
}

class NetworkError extends Error {
  constructor(message, statusCode) {
    super(message);
    this.name = 'NetworkError';
    this.statusCode = statusCode;
  }
}

// 使用自定义错误
function validateUser(user) {
  if (!user.name) {
    throw new ValidationError('姓名不能为空', 'name');
  }
  
  if (!user.email) {
    throw new ValidationError('邮箱不能为空', 'email');
  }
  
  if (user.age < 0) {
    throw new ValidationError('年龄不能为负数', 'age');
  }
}

function simulateNetworkRequest(url) {
  // 模拟网络请求
  const random = Math.random();
  
  if (random < 0.3) {
    throw new NetworkError('网络连接超时', 408);
  } else if (random < 0.6) {
    throw new NetworkError('服务器内部错误', 500);
  }
  
  return { data: '请求成功', status: 200 };
}

// 错误处理示例
function processUserData(userData) {
  try {
    validateUser(userData);
    console.log('用户数据验证通过');
    
    let response = simulateNetworkRequest('/api/users');
    console.log('网络请求成功:', response);
    
  } catch (error) {
    if (error instanceof ValidationError) {
      console.log(`验证错误 [${error.field}]: ${error.message}`);
    } else if (error instanceof NetworkError) {
      console.log(`网络错误 [${error.statusCode}]: ${error.message}`);
    } else {
      console.log('未知错误:', error.message);
    }
  }
}

// 测试不同的错误情况
console.log('\n测试验证错误:');
processUserData({ name: '', email: 'test@example.com', age: 25 });

console.log('\n测试网络错误:');
for (let i = 0; i < 3; i++) {
  console.log(`\n尝试 ${i + 1}:`);
  processUserData({ name: 'Alice', email: 'alice@example.com', age: 25 });
}

最佳实践

条件语句最佳实践

// 1. 使用严格相等
if (value === 'expected') { // 推荐
  // ...
}

if (value == 'expected') { // 不推荐
  // ...
}

// 2. 避免深层嵌套
// 不好的写法
function processUser(user) {
  if (user) {
    if (user.isActive) {
      if (user.hasPermission) {
        if (user.age >= 18) {
          return '处理用户';
        } else {
          return '用户未成年';
        }
      } else {
        return '用户无权限';
      }
    } else {
      return '用户未激活';
    }
  } else {
    return '用户不存在';
  }
}

// 好的写法(早期返回)
function processUserBetter(user) {
  if (!user) return '用户不存在';
  if (!user.isActive) return '用户未激活';
  if (!user.hasPermission) return '用户无权限';
  if (user.age < 18) return '用户未成年';
  
  return '处理用户';
}

// 3. 使用对象映射替代长switch
const statusMessages = {
  pending: '待处理',
  processing: '处理中',
  completed: '已完成',
  failed: '失败'
};

function getStatusMessage(status) {
  return statusMessages[status] || '未知状态';
}

循环最佳实践

// 1. 选择合适的循环类型
// 遍历数组元素 - 使用for...of
const numbers = [1, 2, 3, 4, 5];
for (const num of numbers) {
  console.log(num);
}

// 遍历对象属性 - 使用for...in或Object.keys()
const obj = { a: 1, b: 2, c: 3 };
for (const key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(key, obj[key]);
  }
}

// 或者
Object.keys(obj).forEach(key => {
  console.log(key, obj[key]);
});

// 2. 避免在循环中进行昂贵的操作
// 不好的写法
for (let i = 0; i < array.length; i++) {
  const expensiveResult = expensiveFunction(); // 每次都调用
  // ...
}

// 好的写法
const expensiveResult = expensiveFunction(); // 只调用一次
for (let i = 0; i < array.length; i++) {
  // 使用expensiveResult
}

// 3. 使用数组方法替代手动循环
// 不好的写法
const doubled = [];
for (let i = 0; i < numbers.length; i++) {
  doubled.push(numbers[i] * 2);
}

// 好的写法
const doubled2 = numbers.map(num => num * 2);

// 4. 缓存数组长度(在性能敏感的场景)
const len = largeArray.length;
for (let i = 0; i < len; i++) {
  // 处理largeArray[i]
}

错误处理最佳实践

// 1. 具体的错误信息
function divide(a, b) {
  if (typeof a !== 'number' || typeof b !== 'number') {
    throw new TypeError('参数必须是数字');
  }
  
  if (b === 0) {
    throw new Error('除数不能为零');
  }
  
  return a / b;
}

// 2. 错误边界和恢复
function safeParseJSON(jsonString, defaultValue = null) {
  try {
    return JSON.parse(jsonString);
  } catch (error) {
    console.warn('JSON解析失败,使用默认值:', error.message);
    return defaultValue;
  }
}

// 3. 异步错误处理
async function fetchUserData(userId) {
  try {
    const response = await fetch(`/api/users/${userId}`);
    
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }
    
    const userData = await response.json();
    return userData;
    
  } catch (error) {
    console.error('获取用户数据失败:', error.message);
    throw error; // 重新抛出,让调用者处理
  }
}

// 4. 错误日志记录
function logError(error, context = {}) {
  const errorInfo = {
    message: error.message,
    stack: error.stack,
    timestamp: new Date().toISOString(),
    context: context
  };
  
  console.error('错误详情:', errorInfo);
  // 在实际应用中,这里可能会发送到错误监控服务
}

本章总结

本章详细介绍了JavaScript的控制结构和流程控制:

  1. 条件语句:掌握了if、switch语句的使用和最佳实践
  2. 循环语句:学习了for、for…in、for…of、while、do…while等循环结构
  3. 跳转语句:理解了break、continue、return的作用和使用场景
  4. 异常处理:掌握了try…catch…finally和自定义错误的处理方法
  5. 最佳实践:学习了编写高质量、可维护代码的技巧

这些控制结构是编程的基础,熟练掌握它们对于编写逻辑清晰、性能良好的JavaScript程序至关重要。

下一章我们将学习JavaScript的函数和作用域。