JavaScript精通Skill javascript-mastery

这个技能提供全面的JavaScript学习和参考材料,涵盖从基础到高级的33+个核心编程概念,帮助开发者掌握JavaScript语言特性,用于前端开发、代码调试、教学培训和项目实践。关键词:JavaScript, 编程语言, 前端开发, 概念学习, 代码调试, 教学资源, Web开发, 异步编程, 函数式编程, ES6+特性。

前端开发 0 次安装 0 次浏览 更新于 3/21/2026

name: JavaScript精通 description: “全面的JavaScript参考,涵盖每位开发者都应知道的33+个关键概念。从基础如原始类型和闭包,到高级模式如async/await和函数式编程。用于解释JS概念、调试JavaScript问题或教学JavaScript基础。”

🧠 JavaScript精通

每位开发者都应知道的33+个关键JavaScript概念,灵感来自 33-js-concepts

何时使用此技能

使用此技能当:

  • 解释JavaScript概念
  • 调试棘手的JS行为
  • 教学JavaScript基础
  • 审查代码以遵循JS最佳实践
  • 理解语言特性

1. 基础

1.1 原始类型

JavaScript有7种原始类型:

// 字符串
const str = "hello";

// 数字(整数和浮点数)
const num = 42;
const float = 3.14;

// BigInt(用于大整数)
const big = 9007199254740991n;

// 布尔值
const bool = true;

// 未定义
let undef; // undefined

// 空值
const empty = null;

// 符号(唯一标识符)
const sym = Symbol("description");

关键点

  • 原始类型是不可变的
  • 通过值传递
  • typeof null === "object" 是一个历史错误

1.2 类型强制转换

JavaScript隐式转换类型:

// 字符串强制转换
"5" + 3; // "53"(数字→字符串)
"5" - 3; // 2    (字符串→数字)

// 布尔强制转换
Boolean(""); // false
Boolean("hello"); // true
Boolean(0); // false
Boolean([]); // true (!)

// 相等性强制转换
"5" == 5; // true  (强制转换)
"5" === 5; // false (严格)

假值(共8个): false, 0, -0, 0n, "", null, undefined, NaN

1.3 相等运算符

// == (宽松相等) - 强制转换类型
null == undefined; // true
"1" == 1; // true

// === (严格相等) - 无强制转换
null === undefined; // false
"1" === 1; // false

// Object.is() - 处理边界情况
Object.is(NaN, NaN); // true(NaN === NaN 是 false!)
Object.is(-0, 0); // false(0 === -0 是 true!)

规则:除非有特定原因,否则始终使用 ===


2. 作用域与闭包

2.1 作用域类型

// 全局作用域
var globalVar = "global";

function outer() {
  // 函数作用域
  var functionVar = "function";

  if (true) {
    // 块作用域(仅限let/const)
    let blockVar = "block";
    const alsoBlock = "block";
    var notBlock = "function"; // var 忽略块作用域!
  }
}

2.2 闭包

闭包是一个函数,它记住其词法作用域:

function createCounter() {
  let count = 0; // “闭包”变量

  return {
    increment() {
      return ++count;
    },
    decrement() {
      return --count;
    },
    getCount() {
      return count;
    },
  };
}

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

常见用例

  • 数据隐私(模块模式)
  • 函数工厂
  • 部分应用
  • 记忆化

2.3 var vs let vs const

// var - 函数作用域,提升,可重新声明
var x = 1;
var x = 2; // 可行

// let - 块作用域,提升(TDZ),不可重新声明
let y = 1;
// let y = 2; // 错误!

// const - 类似let,但不可重新赋值
const z = 1;
// z = 2; // 错误!

// 但是:const对象是可变的
const obj = { a: 1 };
obj.a = 2; // 可行
obj.b = 3; // 可行

3. 函数与执行

3.1 调用栈

function first() {
  console.log("first start");
  second();
  console.log("first end");
}

function second() {
  console.log("second");
}

first();
// 输出:
// "first start"
// "second"
// "first end"

栈溢出示例:

function infinite() {
  infinite(); // 无基本情况!
}
infinite(); // RangeError: 最大调用栈大小超出

3.2 提升

// 变量提升
console.log(a); // undefined(提升,但未初始化)
var a = 5;

console.log(b); // ReferenceError(TDZ)
let b = 5;

// 函数提升
sayHi(); // 可行!
function sayHi() {
  console.log("Hi!");
}

// 函数表达式不提升
sayBye(); // TypeError
var sayBye = function () {
  console.log("Bye!");
};

3.3 this 关键字

// 全局上下文
console.log(this); // window(浏览器)或 global(Node)

// 对象方法
const obj = {
  name: "Alice",
  greet() {
    console.log(this.name); // "Alice"
  },
};

// 箭头函数(词法this)
const obj2 = {
  name: "Bob",
  greet: () => {
    console.log(this.name); // undefined(继承外部this)
  },
};

// 显式绑定
function greet() {
  console.log(this.name);
}
greet.call({ name: "Charlie" }); // "Charlie"
greet.apply({ name: "Diana" }); // "Diana"
const bound = greet.bind({ name: "Eve" });
bound(); // "Eve"

4. 事件循环与异步

4.1 事件循环

console.log("1");

setTimeout(() => console.log("2"), 0);

Promise.resolve().then(() => console.log("3"));

console.log("4");

// 输出:1, 4, 3, 2
// 为什么?微任务(Promises)在宏任务(setTimeout)之前运行

执行顺序

  1. 同步代码(调用栈)
  2. 微任务(Promise回调,queueMicrotask)
  3. 宏任务(setTimeout,setInterval,I/O)

4.2 回调

// 回调模式
function fetchData(callback) {
  setTimeout(() => {
    callback(null, { data: "result" });
  }, 1000);
}

// 错误优先约定
fetchData((error, result) => {
  if (error) {
    console.error(error);
    return;
  }
  console.log(result);
});

// 回调地狱(避免这个!)
getData((data) => {
  processData(data, (processed) => {
    saveData(processed, (saved) => {
      notify(saved, () => {
        // 😱 金字塔困境
      });
    });
  });
});

4.3 承诺

// 创建Promise
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Success!");
    // 或:reject(new Error("Failed!"));
  }, 1000);
});

// 消费Promises
promise
  .then((result) => console.log(result))
  .catch((error) => console.error(error))
  .finally(() => console.log("Done"));

// Promise组合器
Promise.all([p1, p2, p3]); // 所有必须成功
Promise.allSettled([p1, p2]); // 等待所有,获取状态
Promise.race([p1, p2]); // 第一个settle的
Promise.any([p1, p2]); // 第一个成功的

4.4 async/await

async function fetchUserData(userId) {
  try {
    const response = await fetch(`/api/users/${userId}`);
    if (!response.ok) throw new Error("Failed to fetch");
    const user = await response.json();
    return user;
  } catch (error) {
    console.error("Error:", error);
    throw error; // 重新抛出供调用者处理
  }
}

// 并行执行
async function fetchAll() {
  const [users, posts] = await Promise.all([
    fetch("/api/users"),
    fetch("/api/posts"),
  ]);
  return { users, posts };
}

5. 函数式编程

5.1 高阶函数

接受或返回函数的函数:

// 接受函数
const numbers = [1, 2, 3];
const doubled = numbers.map((n) => n * 2); // [2, 4, 6]

// 返回函数
function multiply(a) {
  return function (b) {
    return a * b;
  };
}
const double = multiply(2);
double(5); // 10

5.2 纯函数

// 纯函数:相同输入→相同输出,无副作用
function add(a, b) {
  return a + b;
}

// 非纯函数:修改外部状态
let total = 0;
function addToTotal(value) {
  total += value; // 副作用!
  return total;
}

// 非纯函数:依赖外部状态
function getDiscount(price) {
  return price * globalDiscountRate; // 外部依赖
}

5.3 map, filter, reduce

const users = [
  { name: "Alice", age: 25 },
  { name: "Bob", age: 30 },
  { name: "Charlie", age: 35 },
];

// map:转换每个元素
const names = users.map((u) => u.name);
// ["Alice", "Bob", "Charlie"]

// filter:保留匹配条件的元素
const adults = users.filter((u) => u.age >= 30);
// [{ name: "Bob", ... }, { name: "Charlie", ... }]

// reduce:累加为单个值
const totalAge = users.reduce((sum, u) => sum + u.age, 0);
// 90

// 链式调用
const result = users
  .filter((u) => u.age >= 30)
  .map((u) => u.name)
  .join(", ");
// "Bob, Charlie"

5.4 柯里化与组合

// 柯里化:将f(a, b, c)转换为f(a)(b)(c)
const curry = (fn) => {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    }
    return (...moreArgs) => curried(...args, ...moreArgs);
  };
};

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

// 组合:结合函数
const compose =
  (...fns) =>
  (x) =>
    fns.reduceRight((acc, fn) => fn(acc), x);

const pipe =
  (...fns) =>
  (x) =>
    fns.reduce((acc, fn) => fn(acc), x);

const addOne = (x) => x + 1;
const double = (x) => x * 2;

const addThenDouble = compose(double, addOne);
addThenDouble(5); // 12 = (5 + 1) * 2

const doubleThenAdd = pipe(double, addOne);
doubleThenAdd(5); // 11 = (5 * 2) + 1

6. 对象与原型

6.1 原型继承

// 原型链
const animal = {
  speak() {
    console.log("Some sound");
  },
};

const dog = Object.create(animal);
dog.bark = function () {
  console.log("Woof!");
};

dog.speak(); // "Some sound"(继承)
dog.bark(); // "Woof!"(自有方法)

// ES6类(语法糖)
class Animal {
  speak() {
    console.log("Some sound");
  }
}

class Dog extends Animal {
  bark() {
    console.log("Woof!");
  }
}

6.2 对象方法

const obj = { a: 1, b: 2 };

// 键、值、条目
Object.keys(obj); // ["a", "b"]
Object.values(obj); // [1, 2]
Object.entries(obj); // [["a", 1], ["b", 2]]

// 浅拷贝
const copy = { ...obj };
const copy2 = Object.assign({}, obj);

// 冻结(不可变)
const frozen = Object.freeze({ x: 1 });
frozen.x = 2; // 静默失败(或在严格模式下抛出)

// 密封(无添加/删除,可修改)
const sealed = Object.seal({ x: 1 });
sealed.x = 2; // 可行
sealed.y = 3; // 失败
delete sealed.x; // 失败

7. 现代JavaScript(ES6+)

7.1 解构

// 数组解构
const [first, second, ...rest] = [1, 2, 3, 4, 5];
// first = 1, second = 2, rest = [3, 4, 5]

// 对象解构
const { name, age, city = "Unknown" } = { name: "Alice", age: 25 };
// name = "Alice", age = 25, city = "Unknown"

// 重命名
const { name: userName } = { name: "Bob" };
// userName = "Bob"

// 嵌套
const {
  address: { street },
} = { address: { street: "123 Main" } };

7.2 展开与剩余

// 展开:扩展可迭代对象
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]

const obj1 = { a: 1 };
const obj2 = { ...obj1, b: 2 }; // { a: 1, b: 2 }

// 剩余:收集剩余参数
function sum(...numbers) {
  return numbers.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4); // 10

7.3 模块

// 命名导出
export const PI = 3.14159;
export function square(x) {
  return x * x;
}

// 默认导出
export default class Calculator {}

// 导入
import Calculator, { PI, square } from "./math.js";
import * as math from "./math.js";

// 动态导入
const module = await import("./dynamic.js");

7.4 可选链与空值合并

// 可选链 (?.)
const user = { address: { city: "NYC" } };
const city = user?.address?.city; // "NYC"
const zip = user?.address?.zip; // undefined(无错误)
const fn = user?.getName?.(); // 如果无方法则为undefined

// 空值合并 (??)
const value = null ?? "default"; // "default"
const zero = 0 ?? "default"; // 0(非空值!)
const empty = "" ?? "default"; // ""(非空值!)

// 与 || 比较
const value2 = 0 || "default"; // "default"(0是假值)

快速参考卡

概念 关键点
== vs === 始终使用 ===
var vs let 优先使用 let/const
闭包 函数 + 词法作用域
this 取决于函数如何调用
事件循环 微任务在宏任务之前
纯函数 相同输入 → 相同输出
原型 __proto__ → 原型链
?? vs `

资源