Skip to content

JavaScript

目录

基础语法

变量声明

javascript
// ES6+ 变量声明
let name = 'John'; // 可重新赋值
const age = 25;    // 不可重新赋值
var old = true;    // 旧式声明,不推荐使用

// 变量提升
console.log(hoisted); // undefined
var hoisted = 'I am hoisted';

// 暂时性死区
console.log(temporalDeadZone); // ReferenceError
let temporalDeadZone = 'I am not hoisted';

说明

  • letconst 是块级作用域
  • var 是函数作用域,存在变量提升
  • const 声明的是引用不可变,但对象内容可变
  • 使用 letconst 可以避免变量提升带来的问题

数据类型

javascript
// 基本类型
const str = 'string';          // 字符串
const num = 123;               // 数字
const bool = true;             // 布尔值
const nul = null;              // 空值
const undef = undefined;       // 未定义
const sym = Symbol('unique');  // 符号

// 引用类型
const obj = { name: 'John' };  // 对象
const arr = [1, 2, 3];         // 数组
const func = () => {};         // 函数

// 类型检查
console.log(typeof str);    // 'string'
console.log(typeof num);    // 'number'
console.log(typeof bool);   // 'boolean'
console.log(typeof nul);    // 'object'
console.log(typeof undef);  // 'undefined'
console.log(typeof sym);    // 'symbol'
console.log(typeof obj);    // 'object'
console.log(typeof arr);    // 'object'
console.log(typeof func);   // 'function'

// 类型转换
const numStr = '123';
console.log(Number(numStr));     // 123
console.log(String(123));        // '123'
console.log(Boolean(1));         // true
console.log(Boolean(0));         // false
console.log(Boolean(''));        // false
console.log(Boolean('hello'));   // true

说明

  • JavaScript 有 7 种基本类型和 1 种引用类型
  • 基本类型存储在栈内存中
  • 引用类型存储在堆内存中
  • 使用 typeof 可以检查基本类型
  • 使用 instanceof 可以检查引用类型
  • 类型转换需要注意隐式转换的规则

运算符

javascript
// 算术运算符
const sum = 1 + 2;        // 加法
const diff = 5 - 3;       // 减法
const product = 2 * 3;    // 乘法
const quotient = 6 / 2;   // 除法
const remainder = 5 % 2;  // 取余
const power = 2 ** 3;     // 幂运算

// 比较运算符
const isEqual = 1 === 1;      // 严格相等
const isNotEqual = 1 !== 2;   // 严格不相等
const isGreater = 2 > 1;      // 大于
const isLess = 1 < 2;         // 小于
const isGreaterEqual = 2 >= 2; // 大于等于
const isLessEqual = 1 <= 2;    // 小于等于

// 逻辑运算符
const and = true && false;  // 逻辑与
const or = true || false;   // 逻辑或
const not = !true;          // 逻辑非

// 位运算符
const bitAnd = 5 & 3;      // 按位与
const bitOr = 5 | 3;       // 按位或
const bitXor = 5 ^ 3;      // 按位异或
const bitNot = ~5;         // 按位非
const leftShift = 5 << 1;  // 左移
const rightShift = 5 >> 1; // 右移
const zeroFillRightShift = 5 >>> 1; // 无符号右移

// 赋值运算符
let x = 1;
x += 2;  // x = x + 2
x -= 1;  // x = x - 1
x *= 2;  // x = x * 2
x /= 2;  // x = x / 2
x %= 2;  // x = x % 2
x **= 2; // x = x ** 2

说明

  • 算术运算符用于数学计算
  • 比较运算符返回布尔值
  • 逻辑运算符用于条件判断
  • 位运算符用于二进制操作
  • 赋值运算符用于变量赋值

函数

函数声明

javascript
// 函数声明
function add(a, b) {
  return a + b;
}

// 函数表达式
const subtract = function(a, b) {
  return a - b;
};

// 箭头函数
const multiply = (a, b) => a * b;

// 立即执行函数
(function() {
  console.log('IIFE');
})();

// 函数参数
function greet(name = 'Guest') {
  console.log(`Hello, ${name}!`);
}

// 剩余参数
function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}

// 参数解构
function printUser({ name, age }) {
  console.log(`${name} is ${age} years old`);
}

说明

  • 函数声明会被提升
  • 函数表达式不会被提升
  • 箭头函数没有自己的 this
  • 立即执行函数可以创建独立作用域
  • 函数参数可以有默认值
  • 剩余参数可以接收任意数量的参数
  • 参数解构可以方便地获取对象属性

闭包

javascript
// 基本闭包
function createCounter() {
  let count = 0;
  return {
    increment() {
      count++;
      return count;
    },
    getCount() {
      return count;
    }
  };
}

const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.getCount());  // 1

// 模块模式
const module = (function() {
  let privateVar = 'private';
  
  function privateMethod() {
    console.log(privateVar);
  }
  
  return {
    publicMethod() {
      privateMethod();
    }
  };
})();

// 柯里化
function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    }
    return function(...moreArgs) {
      return curried.apply(this, args.concat(moreArgs));
    };
  };
}

const add = (a, b, c) => a + b + c;
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3)); // 6

说明

  • 闭包可以访问外部函数的作用域
  • 闭包可以创建私有变量和方法
  • 闭包可以用于模块化开发
  • 闭包可以用于函数式编程
  • 闭包需要注意内存泄漏问题

高阶函数

javascript
// 函数作为参数
function map(arr, fn) {
  const result = [];
  for (let i = 0; i < arr.length; i++) {
    result.push(fn(arr[i]));
  }
  return result;
}

const numbers = [1, 2, 3];
const doubled = map(numbers, x => x * 2);
console.log(doubled); // [2, 4, 6]

// 函数作为返回值
function multiply(x) {
  return function(y) {
    return x * y;
  };
}

const multiplyByTwo = multiply(2);
console.log(multiplyByTwo(3)); // 6

// 函数组合
function compose(...fns) {
  return function(x) {
    return fns.reduceRight((y, f) => f(y), x);
  };
}

const addOne = x => x + 1;
const double = x => x * 2;
const addOneAndDouble = compose(double, addOne);
console.log(addOneAndDouble(3)); // 8

说明

  • 高阶函数可以接收函数作为参数
  • 高阶函数可以返回函数
  • 高阶函数可以用于函数组合
  • 高阶函数可以用于函数式编程
  • 高阶函数可以提高代码复用性

异步编程

Promise

javascript
// 基本用法
const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Data fetched');
    }, 1000);
  });
};

fetchData()
  .then(data => console.log(data))
  .catch(error => console.error(error));

// Promise 链
fetchData()
  .then(data => data.toUpperCase())
  .then(data => console.log(data))
  .catch(error => console.error(error));

// Promise.all
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);

Promise.all([promise1, promise2, promise3])
  .then(values => console.log(values)) // [1, 2, 3]
  .catch(error => console.error(error));

// Promise.race
Promise.race([promise1, promise2, promise3])
  .then(value => console.log(value)) // 1
  .catch(error => console.error(error));

说明

  • Promise 用于处理异步操作
  • Promise 有三种状态:pending、fulfilled、rejected
  • Promise 可以链式调用
  • Promise.all 等待所有 Promise 完成
  • Promise.race 返回第一个完成的 Promise

Async/Await

javascript
// 基本用法
async function getData() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

// 并行请求
async function getMultipleData() {
  try {
    const [data1, data2] = await Promise.all([
      fetchData(),
      fetchData()
    ]);
    console.log(data1, data2);
  } catch (error) {
    console.error(error);
  }
}

// 错误处理
async function handleErrors() {
  try {
    const data = await fetchData();
    return data;
  } catch (error) {
    console.error('Error:', error);
    throw error;
  } finally {
    console.log('Cleanup');
  }
}

说明

  • async/await 是 Promise 的语法糖
  • async 函数总是返回 Promise
  • await 只能在 async 函数中使用
  • try/catch 可以处理异步错误
  • finally 块总是会执行

ES6+ 特性

解构赋值

javascript
// 对象解构
const person = { name: 'John', age: 25 };
const { name, age } = person;
console.log(name, age); // John 25

// 数组解构
const numbers = [1, 2, 3];
const [first, second] = numbers;
console.log(first, second); // 1 2

// 嵌套解构
const user = {
  name: 'John',
  address: {
    city: 'New York',
    country: 'USA'
  }
};
const { name, address: { city } } = user;
console.log(name, city); // John New York

// 默认值
const { name = 'Guest', age = 0 } = {};
console.log(name, age); // Guest 0

说明

  • 解构赋值可以简化代码
  • 可以解构对象和数组
  • 支持嵌套解构
  • 可以设置默认值
  • 可以用于函数参数

展开运算符

javascript
// 数组展开
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2];
console.log(combined); // [1, 2, 3, 4, 5, 6]

// 对象展开
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const merged = { ...obj1, ...obj2 };
console.log(merged); // { a: 1, b: 2 }

// 函数参数
function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3)); // 6

// 复制对象
const original = { a: 1, b: 2 };
const copy = { ...original };
console.log(copy); // { a: 1, b: 2 }

说明

  • 展开运算符可以展开数组和对象
  • 可以用于合并数组和对象
  • 可以用于函数参数
  • 可以用于复制对象
  • 可以用于创建新对象

javascript
// 基本类
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

// 继承
class Student extends Person {
  constructor(name, age, grade) {
    super(name, age);
    this.grade = grade;
  }

  study() {
    console.log(`${this.name} is studying`);
  }
}

// 静态方法
class MathUtils {
  static add(a, b) {
    return a + b;
  }
}

// 私有字段
class BankAccount {
  #balance = 0;

  deposit(amount) {
    this.#balance += amount;
  }

  getBalance() {
    return this.#balance;
  }
}

说明

  • 类是对象的模板
  • 类可以继承
  • 类有构造函数
  • 类有方法
  • 类有静态方法
  • 类有私有字段

最佳实践

1. 代码风格

  • 使用 ESLint
  • 遵循 Airbnb 风格指南
  • 使用 Prettier 格式化
  • 添加适当的注释
  • 使用有意义的变量名
  • 保持代码简洁

2. 性能优化

  • 避免全局变量
  • 使用事件委托
  • 合理使用闭包
  • 避免内存泄漏
  • 使用防抖和节流
  • 优化循环和递归

3. 错误处理

  • 使用 try-catch
  • 合理使用 Promise
  • 添加错误边界
  • 记录错误日志
  • 优雅降级
  • 用户友好的错误提示

4. 测试

  • 单元测试
  • 集成测试
  • 端到端测试
  • 测试覆盖率
  • 自动化测试
  • 持续集成

学习资源

在线教程

视频课程

  • 慕课网
  • 极客时间
  • B站技术区
  • YouTube 技术频道
  • Udemy
  • Coursera

工具推荐

启航团队技术文档