javascript-mastery
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese🧠 JavaScript Mastery
🧠 JavaScript 精通指南
33+ essential JavaScript concepts every developer should know, inspired by 33-js-concepts.
每位开发者都应掌握的33+个JavaScript核心概念,灵感来源于33-js-concepts。
When to Use This Skill
何时使用本技能
Use this skill when:
- Explaining JavaScript concepts
- Debugging tricky JS behavior
- Teaching JavaScript fundamentals
- Reviewing code for JS best practices
- Understanding language quirks
在以下场景使用本技能:
- 讲解JavaScript概念
- 调试复杂的JS行为
- 教授JavaScript基础知识
- 审查JS代码的最佳实践
- 理解语言特性 quirks
1. Fundamentals
1. 基础知识
1.1 Primitive Types
1.1 基本类型
JavaScript has 7 primitive types:
javascript
// String
const str = "hello";
// Number (integers and floats)
const num = 42;
const float = 3.14;
// BigInt (for large integers)
const big = 9007199254740991n;
// Boolean
const bool = true;
// Undefined
let undef; // undefined
// Null
const empty = null;
// Symbol (unique identifiers)
const sym = Symbol("description");Key points:
- Primitives are immutable
- Passed by value
- is a historical bug
typeof null === "object"
JavaScript有7种基本类型:
javascript
// String
const str = "hello";
// Number (整数和浮点数)
const num = 42;
const float = 3.14;
// BigInt (用于大整数)
const big = 9007199254740991n;
// Boolean
const bool = true;
// Undefined
let undef; // undefined
// Null
const empty = null;
// Symbol (唯一标识符)
const sym = Symbol("description");核心要点:
- 基本类型是不可变的
- 按值传递
- 是历史遗留bug
typeof null === "object"
1.2 Type Coercion
1.2 类型转换
JavaScript implicitly converts types:
javascript
// String coercion
"5" + 3; // "53" (number → string)
"5" - 3; // 2 (string → number)
// Boolean coercion
Boolean(""); // false
Boolean("hello"); // true
Boolean(0); // false
Boolean([]); // true (!)
// Equality coercion
"5" == 5; // true (coerces)
"5" === 5; // false (strict)Falsy values (8 total):
, , , , , , ,
false0-00n""nullundefinedNaNJavaScript会隐式转换类型:
javascript
// 字符串转换
"5" + 3; // "53" (数字 → 字符串)
"5" - 3; // 2 (字符串 → 数字)
// 布尔值转换
Boolean(""); // false
Boolean("hello"); // true
Boolean(0); // false
Boolean([]); // true (!)
// 相等性转换
"5" == 5; // true (会转换类型)
"5" === 5; // false (严格相等,不转换)假值(共8个):
, , , , , , ,
false0-00n""nullundefinedNaN1.3 Equality Operators
1.3 相等运算符
javascript
// == (loose equality) - coerces types
null == undefined; // true
"1" == 1; // true
// === (strict equality) - no coercion
null === undefined; // false
"1" === 1; // false
// Object.is() - handles edge cases
Object.is(NaN, NaN); // true (NaN === NaN is false!)
Object.is(-0, 0); // false (0 === -0 is true!)Rule: Always use unless you have a specific reason not to.
===javascript
// == (松散相等) - 会转换类型
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. Scope & Closures
2. 作用域与闭包
2.1 Scope Types
2.1 作用域类型
javascript
// Global scope
var globalVar = "global";
function outer() {
// Function scope
var functionVar = "function";
if (true) {
// Block scope (let/const only)
let blockVar = "block";
const alsoBlock = "block";
var notBlock = "function"; // var ignores blocks!
}
}javascript
// 全局作用域
var globalVar = "global";
function outer() {
// 函数作用域
var functionVar = "function";
if (true) {
// 块级作用域(仅let/const)
let blockVar = "block";
const alsoBlock = "block";
var notBlock = "function"; // var 会忽略块级作用域!
}
}2.2 Closures
2.2 闭包
A closure is a function that remembers its lexical scope:
javascript
function createCounter() {
let count = 0; // "closed over" variable
return {
increment() {
return ++count;
},
decrement() {
return --count;
},
getCount() {
return count;
},
};
}
const counter = createCounter();
counter.increment(); // 1
counter.increment(); // 2
counter.getCount(); // 2Common use cases:
- Data privacy (module pattern)
- Function factories
- Partial application
- Memoization
闭包是指能记住其词法作用域的函数:
javascript
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常见用例:
- 数据隐私(模块模式)
- 函数工厂
- 部分应用
- 记忆化(Memoization)
2.3 var vs let vs const
2.3 var vs let vs const
javascript
// var - function scoped, hoisted, can redeclare
var x = 1;
var x = 2; // OK
// let - block scoped, hoisted (TDZ), no redeclare
let y = 1;
// let y = 2; // Error!
// const - like let, but can't reassign
const z = 1;
// z = 2; // Error!
// BUT: const objects are mutable
const obj = { a: 1 };
obj.a = 2; // OK
obj.b = 3; // OKjavascript
// 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. Functions & Execution
3. 函数与执行
3.1 Call Stack
3.1 调用栈
javascript
function first() {
console.log("first start");
second();
console.log("first end");
}
function second() {
console.log("second");
}
first();
// Output:
// "first start"
// "second"
// "first end"Stack overflow example:
javascript
function infinite() {
infinite(); // No base case!
}
infinite(); // RangeError: Maximum call stack size exceededjavascript
function first() {
console.log("first start");
second();
console.log("first end");
}
function second() {
console.log("second");
}
first();
// 输出:
// "first start"
// "second"
// "first end"栈溢出示例:
javascript
function infinite() {
infinite(); // 没有基线条件!
}
infinite(); // RangeError: 超出最大调用栈大小3.2 Hoisting
3.2 变量提升
javascript
// Variable hoisting
console.log(a); // undefined (hoisted, not initialized)
var a = 5;
console.log(b); // ReferenceError (TDZ)
let b = 5;
// Function hoisting
sayHi(); // Works!
function sayHi() {
console.log("Hi!");
}
// Function expressions don't hoist
sayBye(); // TypeError
var sayBye = function () {
console.log("Bye!");
};javascript
// 变量提升
console.log(a); // undefined (已提升,但未初始化)
var a = 5;
console.log(b); // ReferenceError (暂时性死区)
let b = 5;
// 函数提升
sayHi(); // 可以正常执行!
function sayHi() {
console.log("Hi!");
}
// 函数表达式不会被提升
sayBye(); // TypeError
var sayBye = function () {
console.log("Bye!");
};3.3 this Keyword
3.3 this关键字
javascript
// Global context
console.log(this); // window (browser) or global (Node)
// Object method
const obj = {
name: "Alice",
greet() {
console.log(this.name); // "Alice"
},
};
// Arrow functions (lexical this)
const obj2 = {
name: "Bob",
greet: () => {
console.log(this.name); // undefined (inherits outer this)
},
};
// Explicit binding
function greet() {
console.log(this.name);
}
greet.call({ name: "Charlie" }); // "Charlie"
greet.apply({ name: "Diana" }); // "Diana"
const bound = greet.bind({ name: "Eve" });
bound(); // "Eve"javascript
// 全局上下文
console.log(this); // 浏览器中为window,Node中为global
// 对象方法
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. Event Loop & Async
4. 事件循环与异步
4.1 Event Loop
4.1 事件循环
javascript
console.log("1");
setTimeout(() => console.log("2"), 0);
Promise.resolve().then(() => console.log("3"));
console.log("4");
// Output: 1, 4, 3, 2
// Why? Microtasks (Promises) run before macrotasks (setTimeout)Execution order:
- Synchronous code (call stack)
- Microtasks (Promise callbacks, queueMicrotask)
- Macrotasks (setTimeout, setInterval, I/O)
javascript
console.log("1");
setTimeout(() => console.log("2"), 0);
Promise.resolve().then(() => console.log("3"));
console.log("4");
// 输出: 1, 4, 3, 2
// 原因? 微任务(Promise回调)会在宏任务(setTimeout)之前执行执行顺序:
- 同步代码(调用栈)
- 微任务(Promise回调、queueMicrotask)
- 宏任务(setTimeout、setInterval、I/O)
4.2 Callbacks
4.2 回调函数
javascript
// Callback pattern
function fetchData(callback) {
setTimeout(() => {
callback(null, { data: "result" });
}, 1000);
}
// Error-first convention
fetchData((error, result) => {
if (error) {
console.error(error);
return;
}
console.log(result);
});
// Callback hell (avoid this!)
getData((data) => {
processData(data, (processed) => {
saveData(processed, (saved) => {
notify(saved, () => {
// 😱 Pyramid of doom
});
});
});
});javascript
// 回调模式
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 Promises
4.3 Promise
javascript
// Creating a Promise
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Success!");
// or: reject(new Error("Failed!"));
}, 1000);
});
// Consuming Promises
promise
.then((result) => console.log(result))
.catch((error) => console.error(error))
.finally(() => console.log("Done"));
// Promise combinators
Promise.all([p1, p2, p3]); // All must succeed
Promise.allSettled([p1, p2]); // Wait for all, get status
Promise.race([p1, p2]); // First to settle
Promise.any([p1, p2]); // First to succeedjavascript
// 创建Promise
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Success!");
// 或者: reject(new Error("Failed!"));
}, 1000);
});
// 消费Promise
promise
.then((result) => console.log(result))
.catch((error) => console.error(error))
.finally(() => console.log("Done"));
// Promise组合器
Promise.all([p1, p2, p3]); // 所有Promise必须成功
Promise.allSettled([p1, p2]); // 等待所有Promise完成,返回状态
Promise.race([p1, p2]); // 第一个完成的Promise
Promise.any([p1, p2]); // 第一个成功的Promise4.4 async/await
4.4 async/await
javascript
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; // Re-throw for caller to handle
}
}
// Parallel execution
async function fetchAll() {
const [users, posts] = await Promise.all([
fetch("/api/users"),
fetch("/api/posts"),
]);
return { users, posts };
}javascript
async function fetchUserData(userId) {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) throw new Error("获取数据失败");
const user = await response.json();
return user;
} catch (error) {
console.error("错误:", error);
throw error; // 重新抛出,让调用方处理
}
}
// 并行执行
async function fetchAll() {
const [users, posts] = await Promise.all([
fetch("/api/users"),
fetch("/api/posts"),
]);
return { users, posts };
}5. Functional Programming
5. 函数式编程
5.1 Higher-Order Functions
5.1 高阶函数
Functions that take or return functions:
javascript
// Takes a function
const numbers = [1, 2, 3];
const doubled = numbers.map((n) => n * 2); // [2, 4, 6]
// Returns a function
function multiply(a) {
return function (b) {
return a * b;
};
}
const double = multiply(2);
double(5); // 10接收函数作为参数或返回函数的函数:
javascript
// 接收函数作为参数
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); // 105.2 Pure Functions
5.2 纯函数
javascript
// Pure: same input → same output, no side effects
function add(a, b) {
return a + b;
}
// Impure: modifies external state
let total = 0;
function addToTotal(value) {
total += value; // Side effect!
return total;
}
// Impure: depends on external state
function getDiscount(price) {
return price * globalDiscountRate; // External dependency
}javascript
// 纯函数: 相同输入→相同输出,无副作用
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
5.3 map, filter, reduce
javascript
const users = [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 30 },
{ name: "Charlie", age: 35 },
];
// map: transform each element
const names = users.map((u) => u.name);
// ["Alice", "Bob", "Charlie"]
// filter: keep elements matching condition
const adults = users.filter((u) => u.age >= 30);
// [{ name: "Bob", ... }, { name: "Charlie", ... }]
// reduce: accumulate into single value
const totalAge = users.reduce((sum, u) => sum + u.age, 0);
// 90
// Chaining
const result = users
.filter((u) => u.age >= 30)
.map((u) => u.name)
.join(", ");
// "Bob, Charlie"javascript
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 Currying & Composition
5.4 柯里化与组合
javascript
// Currying: transform f(a, b, c) into 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
// Composition: combine functions
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) + 1javascript
// 柯里化: 将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) + 16. Objects & Prototypes
6. 对象与原型
6.1 Prototypal Inheritance
6.1 原型继承
javascript
// Prototype chain
const animal = {
speak() {
console.log("Some sound");
},
};
const dog = Object.create(animal);
dog.bark = function () {
console.log("Woof!");
};
dog.speak(); // "Some sound" (inherited)
dog.bark(); // "Woof!" (own method)
// ES6 Classes (syntactic sugar)
class Animal {
speak() {
console.log("Some sound");
}
}
class Dog extends Animal {
bark() {
console.log("Woof!");
}
}javascript
// 原型链
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 Object Methods
6.2 对象方法
javascript
const obj = { a: 1, b: 2 };
// Keys, values, entries
Object.keys(obj); // ["a", "b"]
Object.values(obj); // [1, 2]
Object.entries(obj); // [["a", 1], ["b", 2]]
// Shallow copy
const copy = { ...obj };
const copy2 = Object.assign({}, obj);
// Freeze (immutable)
const frozen = Object.freeze({ x: 1 });
frozen.x = 2; // Silently fails (or throws in strict mode)
// Seal (no add/delete, can modify)
const sealed = Object.seal({ x: 1 });
sealed.x = 2; // OK
sealed.y = 3; // Fails
delete sealed.x; // Failsjavascript
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. Modern JavaScript (ES6+)
7. 现代JavaScript(ES6+)
7.1 Destructuring
7.1 解构赋值
javascript
// Array destructuring
const [first, second, ...rest] = [1, 2, 3, 4, 5];
// first = 1, second = 2, rest = [3, 4, 5]
// Object destructuring
const { name, age, city = "Unknown" } = { name: "Alice", age: 25 };
// name = "Alice", age = 25, city = "Unknown"
// Renaming
const { name: userName } = { name: "Bob" };
// userName = "Bob"
// Nested
const {
address: { street },
} = { address: { street: "123 Main" } };javascript
// 数组解构
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 Spread & Rest
7.2 展开与剩余运算符
javascript
// Spread: expand iterable
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 }
// Rest: collect remaining
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4); // 10javascript
// 展开运算符: 展开可迭代对象
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); // 107.3 Modules
7.3 模块
javascript
// Named exports
export const PI = 3.14159;
export function square(x) {
return x * x;
}
// Default export
export default class Calculator {}
// Importing
import Calculator, { PI, square } from "./math.js";
import * as math from "./math.js";
// Dynamic import
const module = await import("./dynamic.js");javascript
// 具名导出
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 Optional Chaining & Nullish Coalescing
7.4 可选链与空值合并运算符
javascript
// Optional chaining (?.)
const user = { address: { city: "NYC" } };
const city = user?.address?.city; // "NYC"
const zip = user?.address?.zip; // undefined (no error)
const fn = user?.getName?.(); // undefined if no method
// Nullish coalescing (??)
const value = null ?? "default"; // "default"
const zero = 0 ?? "default"; // 0 (not nullish!)
const empty = "" ?? "default"; // "" (not nullish!)
// Compare with ||
const value2 = 0 || "default"; // "default" (0 is falsy)javascript
// 可选链 (?.)
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(0不是空值!)
const empty = "" ?? "default"; // ""(空字符串不是空值!)
// 与||对比
const value2 = 0 || "default"; // "default"(0是假值)Quick Reference Card
快速参考卡片
| Concept | Key Point |
|---|---|
| Always use |
| Prefer |
| Closures | Function + lexical scope |
| Depends on how function is called |
| Event loop | Microtasks before macrotasks |
| Pure functions | Same input → same output |
| Prototypes | |
| |
| 概念 | 核心要点 |
|---|---|
| 始终使用 |
| 优先使用 |
| 闭包 | 函数 + 词法作用域 |
| 取决于函数的调用方式 |
| 事件循环 | 微任务优先于宏任务执行 |
| 纯函数 | 相同输入→相同输出 |
| 原型 | |
|