fix(eslint): reduce warnings in GitHub Actions deployment

- Disable formatting rules (handled by Prettier)
- Relaxed strict Vue/JS rules for demo code compatibility
- Fix syntax errors in ApiPlayground and VoiceCloningDemo
- Fix duplicate else-if condition in ApiPlayground
- Fix Promise executor async pattern in AutoregressiveAudioDemo
- Add TypeScript file support to ESLint config

Warnings reduced from 295 to 251 problems.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
sanbuphy
2026-02-18 17:38:10 +08:00
parent 8b01686e68
commit 0eba9e87e9
456 changed files with 28450 additions and 9677 deletions
@@ -17,55 +17,106 @@
<button
v-for="tab in tabs"
:key="tab.id"
@click="activeTab = tab.id"
class="tab-btn"
:class="{ active: activeTab === tab.id }"
@click="activeTab = tab.id"
>
{{ tab.label }}
</button>
</div>
<!-- 回调函数 -->
<div v-if="activeTab === 'callback'" class="tab-content">
<div
v-if="activeTab === 'callback'"
class="tab-content"
>
<div class="callback-demo">
<div class="concept-card">
<div class="concept-icon">🔄</div>
<div class="concept-title">回调函数 (Callback)</div>
<div class="concept-icon">
🔄
</div>
<div class="concept-title">
回调函数 (Callback)
</div>
<div class="concept-desc">
把函数作为参数传给另一个函数等操作完成后再调用它这是最早的异步处理方式
</div>
</div>
<div class="code-example">
<div class="code-title">回调函数示例</div>
<div class="code-title">
回调函数示例
</div>
<div class="code-block">
<div class="code-line comment">// 模拟异步操作(如网络请求)</div>
<div class="code-line">function fetchData(callback) {</div>
<div class="code-line indent">setTimeout(() => {</div>
<div class="code-line indent indent">const data = { id: 1, name: "数据" }</div>
<div class="code-line indent indent">callback(data)</div>
<div class="code-line indent">}, 1000)</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line comment">// 使用回调</div>
<div class="code-line">fetchData(function(data) {</div>
<div class="code-line indent">console.log("收到数据:", data)</div>
<div class="code-line">})</div>
<div class="code-line comment">
// 模拟异步操作(如网络请求)
</div>
<div class="code-line">
function fetchData(callback) {
</div>
<div class="code-line indent">
setTimeout(() => {
</div>
<div class="code-line indent indent">
const data = { id: 1, name: "数据" }
</div>
<div class="code-line indent indent">
callback(data)
</div>
<div class="code-line indent">
}, 1000)
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line comment">
// 使用回调
</div>
<div class="code-line">
fetchData(function(data) {
</div>
<div class="code-line indent">
console.log("收到数据:", data)
</div>
<div class="code-line">
})
</div>
</div>
</div>
<div class="callback-problem">
<div class="problem-title"> 回调地狱问题</div>
<div class="problem-title">
回调地狱问题
</div>
<div class="code-block bad">
<div class="code-line">getData(function(a) {</div>
<div class="code-line indent">getMoreData(a, function(b) {</div>
<div class="code-line indent indent">getMoreData(b, function(c) {</div>
<div class="code-line indent indent indent">getMoreData(c, function(d) {</div>
<div class="code-line indent indent indent indent">// 无限嵌套...</div>
<div class="code-line indent indent indent">})</div>
<div class="code-line indent indent">})</div>
<div class="code-line indent">})</div>
<div class="code-line">})</div>
<div class="code-line">
getData(function(a) {
</div>
<div class="code-line indent">
getMoreData(a, function(b) {
</div>
<div class="code-line indent indent">
getMoreData(b, function(c) {
</div>
<div class="code-line indent indent indent">
getMoreData(c, function(d) {
</div>
<div class="code-line indent indent indent indent">
// 无限嵌套...
</div>
<div class="code-line indent indent indent">
})
</div>
<div class="code-line indent indent">
})
</div>
<div class="code-line indent">
})
</div>
<div class="code-line">
})
</div>
</div>
<div class="problem-desc">
多个异步操作嵌套会导致代码难以维护被称为"回调地狱"
@@ -75,82 +126,173 @@
</div>
<!-- Promise -->
<div v-else-if="activeTab === 'promise'" class="tab-content">
<div
v-else-if="activeTab === 'promise'"
class="tab-content"
>
<div class="promise-demo">
<div class="promise-states">
<div class="state-title">Promise 的三种状态</div>
<div class="state-title">
Promise 的三种状态
</div>
<div class="states-diagram">
<div class="state-box pending" :class="{ active: promiseState === 'pending' }">
<div class="state-name">Pending</div>
<div class="state-desc">进行中</div>
<div
class="state-box pending"
:class="{ active: promiseState === 'pending' }"
>
<div class="state-name">
Pending
</div>
<div class="state-desc">
进行中
</div>
</div>
<div
v-if="promiseState === 'pending'"
class="state-arrow"
>
</div>
<div class="state-arrow" v-if="promiseState === 'pending'"></div>
<div class="state-branch">
<div class="branch-top">
<div class="state-box fulfilled" :class="{ active: promiseState === 'fulfilled' }">
<div class="state-name">Fulfilled</div>
<div class="state-desc">已成功</div>
<div
class="state-box fulfilled"
:class="{ active: promiseState === 'fulfilled' }"
>
<div class="state-name">
Fulfilled
</div>
<div class="state-desc">
已成功
</div>
</div>
<div
v-if="promiseState === 'fulfilled'"
class="state-arrow"
>
</div>
<div class="state-arrow" v-if="promiseState === 'fulfilled'"></div>
</div>
<div class="branch-bottom">
<div class="state-box rejected" :class="{ active: promiseState === 'rejected' }">
<div class="state-name">Rejected</div>
<div class="state-desc">已失败</div>
<div
class="state-box rejected"
:class="{ active: promiseState === 'rejected' }"
>
<div class="state-name">
Rejected
</div>
<div class="state-desc">
已失败
</div>
</div>
<div
v-if="promiseState === 'rejected'"
class="state-arrow"
>
</div>
<div class="state-arrow" v-if="promiseState === 'rejected'"></div>
</div>
</div>
</div>
<div class="promise-actions">
<button @click="simulatePromise('fulfilled')" class="action-btn success">
<button
class="action-btn success"
@click="simulatePromise('fulfilled')"
>
模拟成功
</button>
<button @click="simulatePromise('rejected')" class="action-btn error">
<button
class="action-btn error"
@click="simulatePromise('rejected')"
>
模拟失败
</button>
</div>
</div>
<div class="promise-usage">
<div class="code-title">Promise 使用示例</div>
<div class="code-title">
Promise 使用示例
</div>
<div class="code-block">
<div class="code-line comment">// 创建 Promise</div>
<div class="code-line">const promise = new Promise((resolve, reject) => {</div>
<div class="code-line indent">const success = Math.random() > 0.5</div>
<div class="code-line indent">if (success) {</div>
<div class="code-line indent indent">resolve("操作成功!")</div>
<div class="code-line indent">} else {</div>
<div class="code-line indent indent">reject("操作失败!")</div>
<div class="code-line indent">}</div>
<div class="code-line">})</div>
<div class="code-line"></div>
<div class="code-line comment">// 使用 then/catch</div>
<div class="code-line">promise</div>
<div class="code-line indent">.then(result => console.log(result))</div>
<div class="code-line indent">.catch(error => console.error(error))</div>
<div class="code-line comment">
// 创建 Promise
</div>
<div class="code-line">
const promise = new Promise((resolve, reject) => {
</div>
<div class="code-line indent">
const success = Math.random() > 0.5
</div>
<div class="code-line indent">
if (success) {
</div>
<div class="code-line indent indent">
resolve("操作成功!")
</div>
<div class="code-line indent">
} else {
</div>
<div class="code-line indent indent">
reject("操作失败!")
</div>
<div class="code-line indent">
}
</div>
<div class="code-line">
})
</div>
<div class="code-line" />
<div class="code-line comment">
// 使用 then/catch
</div>
<div class="code-line">
promise
</div>
<div class="code-line indent">
.then(result => console.log(result))
</div>
<div class="code-line indent">
.catch(error => console.error(error))
</div>
</div>
<div class="promise-chain">
<div class="chain-title">链式调用</div>
<div class="chain-title">
链式调用
</div>
<div class="chain-visual">
<div class="chain-step">
<div class="step-box">Promise</div>
<div class="step-arrow"></div>
<div class="step-box">
Promise
</div>
<div class="step-arrow">
</div>
</div>
<div class="chain-step">
<div class="step-box then">.then()</div>
<div class="step-arrow"></div>
<div class="step-box then">
.then()
</div>
<div class="step-arrow">
</div>
</div>
<div class="chain-step">
<div class="step-box then">.then()</div>
<div class="step-arrow"></div>
<div class="step-box then">
.then()
</div>
<div class="step-arrow">
</div>
</div>
<div class="chain-step">
<div class="step-box catch">.catch()</div>
<div class="step-box catch">
.catch()
</div>
</div>
</div>
</div>
@@ -159,61 +301,132 @@
</div>
<!-- async/await -->
<div v-else-if="activeTab === 'async'" class="tab-content">
<div
v-else-if="activeTab === 'async'"
class="tab-content"
>
<div class="async-await-demo">
<div class="comparison-view">
<div class="compare-panel promise">
<div class="panel-title">Promise 链式调用</div>
<div class="panel-title">
Promise 链式调用
</div>
<div class="code-block">
<div class="code-line">function fetchUser() {</div>
<div class="code-line indent">return fetch('/user')</div>
<div class="code-line indent indent">.then(res => res.json())</div>
<div class="code-line indent indent">.then(user => {</div>
<div class="code-line indent indent indent">return fetch(`/posts/${user.id}`)</div>
<div class="code-line indent indent">})</div>
<div class="code-line indent indent">.then(res => res.json())</div>
<div class="code-line indent indent">.then(posts => {</div>
<div class="code-line indent indent indent">console.log(posts)</div>
<div class="code-line indent indent">})</div>
<div class="code-line">}</div>
<div class="code-line">
function fetchUser() {
</div>
<div class="code-line indent">
return fetch('/user')
</div>
<div class="code-line indent indent">
.then(res => res.json())
</div>
<div class="code-line indent indent">
.then(user => {
</div>
<div class="code-line indent indent indent">
return fetch(`/posts/${user.id}`)
</div>
<div class="code-line indent indent">
})
</div>
<div class="code-line indent indent">
.then(res => res.json())
</div>
<div class="code-line indent indent">
.then(posts => {
</div>
<div class="code-line indent indent indent">
console.log(posts)
</div>
<div class="code-line indent indent">
})
</div>
<div class="code-line">
}
</div>
</div>
</div>
<div class="compare-panel async">
<div class="panel-title">async/await 语法</div>
<div class="panel-title">
async/await 语法
</div>
<div class="code-block">
<div class="code-line">async function fetchUser() {</div>
<div class="code-line indent">try {</div>
<div class="code-line indent indent">const res = await fetch('/user')</div>
<div class="code-line indent indent">const user = await res.json()</div>
<div class="code-line indent indent">const postRes = await fetch(`/posts/${user.id}`)</div>
<div class="code-line indent indent">const posts = await postRes.json()</div>
<div class="code-line indent indent">console.log(posts)</div>
<div class="code-line indent">} catch (error) {</div>
<div class="code-line indent indent">console.error(error)</div>
<div class="code-line indent">}</div>
<div class="code-line">}</div>
<div class="code-line">
async function fetchUser() {
</div>
<div class="code-line indent">
try {
</div>
<div class="code-line indent indent">
const res = await fetch('/user')
</div>
<div class="code-line indent indent">
const user = await res.json()
</div>
<div class="code-line indent indent">
const postRes = await fetch(`/posts/${user.id}`)
</div>
<div class="code-line indent indent">
const posts = await postRes.json()
</div>
<div class="code-line indent indent">
console.log(posts)
</div>
<div class="code-line indent">
} catch (error) {
</div>
<div class="code-line indent indent">
console.error(error)
</div>
<div class="code-line indent">
}
</div>
<div class="code-line">
}
</div>
</div>
</div>
</div>
<div class="async-playground">
<div class="playground-title">async/await 特点</div>
<div class="playground-title">
async/await 特点
</div>
<div class="feature-grid">
<div class="feature-item">
<div class="feature-icon">📖</div>
<div class="feature-name">更像同步代码</div>
<div class="feature-desc">用同步的方式写异步代码更易读</div>
<div class="feature-icon">
📖
</div>
<div class="feature-name">
更像同步代码
</div>
<div class="feature-desc">
用同步的方式写异步代码更易读
</div>
</div>
<div class="feature-item">
<div class="feature-icon">🎯</div>
<div class="feature-name">错误处理简单</div>
<div class="feature-desc"> try/catch .catch()</div>
<div class="feature-icon">
🎯
</div>
<div class="feature-name">
错误处理简单
</div>
<div class="feature-desc">
try/catch .catch()
</div>
</div>
<div class="feature-item">
<div class="feature-icon"></div>
<div class="feature-name">调试友好</div>
<div class="feature-desc">可以在 debugger 中设置断点</div>
<div class="feature-icon">
</div>
<div class="feature-name">
调试友好
</div>
<div class="feature-desc">
可以在 debugger 中设置断点
</div>
</div>
</div>
@@ -230,41 +443,75 @@
</div>
<!-- 事件循环 -->
<div v-else class="tab-content">
<div
v-else
class="tab-content"
>
<div class="event-loop-demo">
<div class="loop-visual">
<div class="loop-title">事件循环 (Event Loop)</div>
<div class="loop-title">
事件循环 (Event Loop)
</div>
<div class="loop-diagram">
<div class="diagram-section">
<div class="section-title">调用栈 (Call Stack)</div>
<div class="section-title">
调用栈 (Call Stack)
</div>
<div class="stack-box">
<div v-for="(item, i) in callStack" :key="i" class="stack-item">
<div
v-for="(item, i) in callStack"
:key="i"
class="stack-item"
>
{{ item }}
</div>
<div v-if="callStack.length === 0" class="stack-empty"></div>
<div
v-if="callStack.length === 0"
class="stack-empty"
>
</div>
</div>
</div>
<div class="diagram-arrows">
<div class="arrow-right">入栈 </div>
<div class="arrow-left"> </div>
<div class="arrow-right">
</div>
<div class="arrow-left">
出栈
</div>
</div>
<div class="diagram-section">
<div class="section-title">任务队列</div>
<div class="section-title">
任务队列
</div>
<div class="task-queues">
<div class="queue-box">
<div class="queue-title">宏任务 (Macro Tasks)</div>
<div class="queue-title">
宏任务 (Macro Tasks)
</div>
<div class="queue-items">
<div v-for="(task, i) in macroTasks" :key="i" class="task-item macro">
<div
v-for="(task, i) in macroTasks"
:key="i"
class="task-item macro"
>
{{ task }}
</div>
</div>
</div>
<div class="queue-box">
<div class="queue-title">微任务 (Micro Tasks)</div>
<div class="queue-title">
微任务 (Micro Tasks)
</div>
<div class="queue-items">
<div v-for="(task, i) in microTasks" :key="i" class="task-item micro">
<div
v-for="(task, i) in microTasks"
:key="i"
class="task-item micro"
>
{{ task }}
</div>
</div>
@@ -274,7 +521,9 @@
</div>
<div class="loop-rules">
<div class="rule-title">执行规则</div>
<div class="rule-title">
执行规则
</div>
<ol class="rule-list">
<li>执行同步代码调用栈中的代码</li>
<li>调用栈为空时先执行所有微任务</li>
@@ -285,22 +534,38 @@
</div>
<div class="code-challenge">
<div class="challenge-title">🤔 猜猜输出顺序</div>
<div class="challenge-title">
🤔 猜猜输出顺序
</div>
<div class="code-block">
<div class="code-line">console.log("1")</div>
<div class="code-line"></div>
<div class="code-line">setTimeout(() => console.log("2"), 0) <span class="comment">// 宏任务</span></div>
<div class="code-line"></div>
<div class="code-line">Promise.resolve().then(() => console.log("3")) <span class="comment">// 微任务</span></div>
<div class="code-line"></div>
<div class="code-line">console.log("4")</div>
<div class="code-line">
console.log("1")
</div>
<div class="code-line" />
<div class="code-line">
setTimeout(() => console.log("2"), 0) <span class="comment">// 宏任务</span>
</div>
<div class="code-line" />
<div class="code-line">
Promise.resolve().then(() => console.log("3")) <span class="comment">// 微任务</span>
</div>
<div class="code-line" />
<div class="code-line">
console.log("4")
</div>
</div>
<button @click="showEventLoopAnswer" class="answer-btn">
<button
class="answer-btn"
@click="showEventLoopAnswer"
>
{{ showAnswer ? '隐藏答案' : '查看答案' }}
</button>
<div v-if="showAnswer" class="answer-reveal">
<div
v-if="showAnswer"
class="answer-reveal"
>
<div class="output-order">
<div class="order-item">
<span class="order-num">1</span>
@@ -57,10 +57,10 @@ const processCustomer = async (customer, realTime) => {
<button
v-for="m in modes"
:key="m.value"
@click="mode = m.value"
:class="{ 'active': mode === m.value }"
class="mode-btn"
:disabled="isRunning"
@click="mode = m.value"
>
{{ m.label }}
</button>
@@ -75,33 +75,84 @@ const processCustomer = async (customer, realTime) => {
class="stove"
:class="{ 'cooking': customerA.status === 'cooking', 'done': customerA.status === 'done' }"
>
<div class="stove-label">灶位 1</div>
<div class="stove-label">
灶位 1
</div>
<div class="stove-content">
<div v-if="customerA.status === 'cooking'" class="cooking-text">煮面 {{ customerA.time }}s</div>
<div v-if="customerA.status === 'done'" class="done-text"> 完成</div>
<div v-if="customerA.status === 'waiting'" class="waiting-text">空闲</div>
<div
v-if="customerA.status === 'cooking'"
class="cooking-text"
>
煮面 {{ customerA.time }}s
</div>
<div
v-if="customerA.status === 'done'"
class="done-text"
>
完成
</div>
<div
v-if="customerA.status === 'waiting'"
class="waiting-text"
>
空闲
</div>
</div>
</div>
<div
class="stove"
:class="{ 'cooking': customerB.status === 'cooking', 'done': customerB.status === 'done' }"
>
<div class="stove-label">灶位 2</div>
<div class="stove-label">
灶位 2
</div>
<div class="stove-content">
<div v-if="customerB.status === 'cooking'" class="cooking-text">炒饭 {{ customerB.time }}s</div>
<div v-if="customerB.status === 'done'" class="done-text"> 完成</div>
<div v-if="customerB.status === 'waiting'" class="waiting-text">空闲</div>
<div
v-if="customerB.status === 'cooking'"
class="cooking-text"
>
炒饭 {{ customerB.time }}s
</div>
<div
v-if="customerB.status === 'done'"
class="done-text"
>
完成
</div>
<div
v-if="customerB.status === 'waiting'"
class="waiting-text"
>
空闲
</div>
</div>
</div>
<div
class="stove"
:class="{ 'cooking': customerC.status === 'cooking', 'done': customerC.status === 'done' }"
>
<div class="stove-label">灶位 3</div>
<div class="stove-label">
灶位 3
</div>
<div class="stove-content">
<div v-if="customerC.status === 'cooking'" class="cooking-text">烤鱼 {{ customerC.time }}s</div>
<div v-if="customerC.status === 'done'" class="done-text"> 完成</div>
<div v-if="customerC.status === 'waiting'" class="waiting-text">空闲</div>
<div
v-if="customerC.status === 'cooking'"
class="cooking-text"
>
烤鱼 {{ customerC.time }}s
</div>
<div
v-if="customerC.status === 'done'"
class="done-text"
>
完成
</div>
<div
v-if="customerC.status === 'waiting'"
class="waiting-text"
>
空闲
</div>
</div>
</div>
</div>
@@ -111,51 +162,106 @@ const processCustomer = async (customer, realTime) => {
<div class="customers">
<h4>顾客</h4>
<div class="customer-list">
<div class="customer" :class="{ 'served': customerA.status === 'done' }">
<div class="customer-avatar">👤</div>
<div class="customer-info">
<div class="customer-name">顾客 A</div>
<div class="customer-order">煮面 ({{ customerA.time }})</div>
<div
class="customer"
:class="{ 'served': customerA.status === 'done' }"
>
<div class="customer-avatar">
👤
</div>
<div class="customer-info">
<div class="customer-name">
顾客 A
</div>
<div class="customer-order">
煮面 ({{ customerA.time }})
</div>
</div>
<div
v-if="customerA.status === 'done'"
class="check-mark"
>
</div>
<div v-if="customerA.status === 'done'" class="check-mark"></div>
</div>
<div class="customer" :class="{ 'served': customerB.status === 'done' }">
<div class="customer-avatar">👤</div>
<div class="customer-info">
<div class="customer-name">顾客 B</div>
<div class="customer-order">炒饭 ({{ customerB.time }})</div>
<div
class="customer"
:class="{ 'served': customerB.status === 'done' }"
>
<div class="customer-avatar">
👤
</div>
<div class="customer-info">
<div class="customer-name">
顾客 B
</div>
<div class="customer-order">
炒饭 ({{ customerB.time }})
</div>
</div>
<div
v-if="customerB.status === 'done'"
class="check-mark"
>
</div>
<div v-if="customerB.status === 'done'" class="check-mark"></div>
</div>
<div class="customer" :class="{ 'served': customerC.status === 'done' }">
<div class="customer-avatar">👤</div>
<div class="customer-info">
<div class="customer-name">顾客 C</div>
<div class="customer-order">烤鱼 ({{ customerC.time }})</div>
<div
class="customer"
:class="{ 'served': customerC.status === 'done' }"
>
<div class="customer-avatar">
👤
</div>
<div class="customer-info">
<div class="customer-name">
顾客 C
</div>
<div class="customer-order">
烤鱼 ({{ customerC.time }})
</div>
</div>
<div
v-if="customerC.status === 'done'"
class="check-mark"
>
</div>
<div v-if="customerC.status === 'done'" class="check-mark"></div>
</div>
</div>
</div>
</div>
<div class="controls">
<button @click="start" :disabled="isRunning" class="btn-start">
<button
:disabled="isRunning"
class="btn-start"
@click="start"
>
{{ isRunning ? '执行中...' : '开始' }}
</button>
<button @click="reset" :disabled="isRunning" class="btn-reset">
<button
:disabled="isRunning"
class="btn-reset"
@click="reset"
>
重置
</button>
</div>
<div class="comparison" v-if="!isRunning && (customerA.status === 'done' || customerB.status === 'done')">
<div
v-if="!isRunning && (customerA.status === 'done' || customerB.status === 'done')"
class="comparison"
>
<div class="comparison-item">
<strong>同步模式</strong> 10 依次执行
</div>
<div class="comparison-item">
<strong>异步模式</strong> 5 同时执行
</div>
<div class="tip">JavaScript 用的就是异步模式遇到耗时操作如网络请求不会傻等而是先去做别的事</div>
<div class="tip">
JavaScript 用的就是异步模式遇到耗时操作如网络请求不会傻等而是先去做别的事
</div>
</div>
<div class="code-display">
@@ -16,82 +16,158 @@
<button
v-for="tab in tabs"
:key="tab.id"
@click="activeTab = tab.id"
class="tab-btn"
:class="{ active: activeTab === tab.id }"
@click="activeTab = tab.id"
>
{{ tab.label }}
</button>
</div>
<!-- 函数基础 -->
<div v-if="activeTab === 'basic'" class="tab-content">
<div
v-if="activeTab === 'basic'"
class="tab-content"
>
<div class="function-showcase">
<div class="code-panel">
<div class="code-title">函数声明方式</div>
<div class="code-title">
函数声明方式
</div>
<div class="code-block">
<div class="code-line comment">// 1. 函数声明</div>
<div class="code-line">function greet(name) {</div>
<div class="code-line indent">return "Hello " + name</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line comment">// 2. 函数表达式</div>
<div class="code-line">const greet = function(name) {</div>
<div class="code-line indent">return "Hello " + name</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line comment">// 3. 箭头函数 (ES6)</div>
<div class="code-line">const greet = (name) => {</div>
<div class="code-line indent">return "Hello " + name</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line comment">// 简化版(单行可省略 return</div>
<div class="code-line">const greet = name => "Hello " + name</div>
<div class="code-line comment">
// 1. 函数声明
</div>
<div class="code-line">
function greet(name) {
</div>
<div class="code-line indent">
return "Hello " + name
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line comment">
// 2. 函数表达式
</div>
<div class="code-line">
const greet = function(name) {
</div>
<div class="code-line indent">
return "Hello " + name
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line comment">
// 3. 箭头函数 (ES6)
</div>
<div class="code-line">
const greet = (name) => {
</div>
<div class="code-line indent">
return "Hello " + name
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line comment">
// 简化版(单行可省略 return)
</div>
<div class="code-line">
const greet = name => "Hello " + name
</div>
</div>
</div>
<div class="playground">
<div class="playground-title">试试调用函数</div>
<div class="playground-title">
试试调用函数
</div>
<div class="input-group">
<input v-model="functionName" placeholder="输入你的名字" />
<button @click="callFunction">调用</button>
<input
v-model="functionName"
placeholder="输入你的名字"
>
<button @click="callFunction">
调用
</button>
</div>
<div class="output">
<span v-if="functionResult" class="result">{{ functionResult }}</span>
<span v-else class="placeholder">点击"调用"按钮看结果...</span>
<span
v-if="functionResult"
class="result"
>{{ functionResult }}</span>
<span
v-else
class="placeholder"
>点击"调用"按钮看结果...</span>
</div>
</div>
</div>
</div>
<!-- 闭包演示 -->
<div v-else-if="activeTab === 'closure'" class="tab-content">
<div
v-else-if="activeTab === 'closure'"
class="tab-content"
>
<div class="closure-visual">
<div class="scenario-selector">
<button @click="closureScenario = 'counter'" :class="{ active: closureScenario === 'counter' }">
<button
:class="{ active: closureScenario === 'counter' }"
@click="closureScenario = 'counter'"
>
计数器
</button>
<button @click="closureScenario = 'config'" :class="{ active: closureScenario === 'config' }">
<button
:class="{ active: closureScenario === 'config' }"
@click="closureScenario = 'config'"
>
配置器
</button>
</div>
<div v-if="closureScenario === 'counter'" class="counter-demo">
<div
v-if="closureScenario === 'counter'"
class="counter-demo"
>
<div class="code-panel small">
<div class="code-line">function createCounter() {</div>
<div class="code-line indent">let count = 0 <span class="comment">// 私有变量</span></div>
<div class="code-line indent">return function() {</div>
<div class="code-line indent indent">count++</div>
<div class="code-line indent indent">return count</div>
<div class="code-line indent">}</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line">const counter = createCounter()</div>
<div class="code-line">
function createCounter() {
</div>
<div class="code-line indent">
let count = 0 <span class="comment">// 私有变量</span>
</div>
<div class="code-line indent">
return function() {
</div>
<div class="code-line indent indent">
count++
</div>
<div class="code-line indent indent">
return count
</div>
<div class="code-line indent">
}
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line">
const counter = createCounter()
</div>
</div>
<div class="closure-animation">
<div class="closure-box">
<div class="box-title">闭包环境</div>
<div class="box-title">
闭包环境
</div>
<div class="closure-var">
<span class="var-label">count = </span>
<span class="var-value">{{ counterValue }}</span>
@@ -99,7 +175,10 @@
</div>
<div class="controls-area">
<button @click="incrementCounter" class="action-btn primary">
<button
class="action-btn primary"
@click="incrementCounter"
>
调用 counter()
</button>
</div>
@@ -116,36 +195,78 @@
</div>
</div>
<div v-else class="config-demo">
<div
v-else
class="config-demo"
>
<div class="code-panel small">
<div class="code-line">function makeMultiplier(times) {</div>
<div class="code-line indent">return function(n) {</div>
<div class="code-line indent indent">return n * times</div>
<div class="code-line indent">}</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line">const double = makeMultiplier(2)</div>
<div class="code-line">const triple = makeMultiplier(3)</div>
<div class="code-line">
function makeMultiplier(times) {
</div>
<div class="code-line indent">
return function(n) {
</div>
<div class="code-line indent indent">
return n * times
</div>
<div class="code-line indent">
}
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line">
const double = makeMultiplier(2)
</div>
<div class="code-line">
const triple = makeMultiplier(3)
</div>
</div>
<div class="multiplier-playground">
<div class="function-list">
<div class="func-item" @click="activeMultiplier = 'double'" :class="{ active: activeMultiplier === 'double' }">
<div class="func-name">double = makeMultiplier(2)</div>
<div class="func-desc">闭包捕获 times = 2</div>
<div
class="func-item"
:class="{ active: activeMultiplier === 'double' }"
@click="activeMultiplier = 'double'"
>
<div class="func-name">
double = makeMultiplier(2)
</div>
<div class="func-desc">
闭包捕获 times = 2
</div>
</div>
<div class="func-item" @click="activeMultiplier = 'triple'" :class="{ active: activeMultiplier === 'triple' }">
<div class="func-name">triple = makeMultiplier(3)</div>
<div class="func-desc">闭包捕获 times = 3</div>
<div
class="func-item"
:class="{ active: activeMultiplier === 'triple' }"
@click="activeMultiplier = 'triple'"
>
<div class="func-name">
triple = makeMultiplier(3)
</div>
<div class="func-desc">
闭包捕获 times = 3
</div>
</div>
</div>
<div class="multiplier-input">
<input v-model.number="multiplyNumber" type="number" placeholder="输入数字" />
<button @click="doMultiply">计算</button>
<input
v-model.number="multiplyNumber"
type="number"
placeholder="输入数字"
>
<button @click="doMultiply">
计算
</button>
</div>
<div v-if="multiplyResult" class="multiply-result">
<div
v-if="multiplyResult"
class="multiply-result"
>
<span class="result-equation">{{ multiplyResult }}</span>
</div>
</div>
@@ -154,23 +275,32 @@
</div>
<!-- 作用域链 -->
<div v-else class="tab-content">
<div
v-else
class="tab-content"
>
<div class="scope-chain-demo">
<div class="nested-visual">
<div class="scope-level global">
<div class="level-title">全局作用域</div>
<div class="level-title">
全局作用域
</div>
<div class="level-vars">
<span class="var-tag">globalVar = "全局"</span>
</div>
<div class="scope-level outer">
<div class="level-title">外层函数作用域</div>
<div class="level-title">
外层函数作用域
</div>
<div class="level-vars">
<span class="var-tag">outerVar = "外层"</span>
</div>
<div class="scope-level inner">
<div class="level-title">内层函数作用域</div>
<div class="level-title">
内层函数作用域
</div>
<div class="level-vars">
<span class="var-tag">innerVar = "内层"</span>
</div>
@@ -180,11 +310,21 @@
</div>
<div class="lookup-demo">
<div class="lookup-title">🔍 变量查找过程作用域链</div>
<div class="lookup-title">
🔍 变量查找过程作用域链
</div>
<div class="lookup-steps">
<div class="lookup-step" v-for="(step, i) in lookupSteps" :key="i">
<div class="step-num">{{ i + 1 }}</div>
<div class="step-content">{{ step }}</div>
<div
v-for="(step, i) in lookupSteps"
:key="i"
class="lookup-step"
>
<div class="step-num">
{{ i + 1 }}
</div>
<div class="step-content">
{{ step }}
</div>
</div>
</div>
@@ -34,16 +34,23 @@ const removeItem = () => {
<div class="webpage-preview">
<div class="browser-bar">
<div class="dots">
<span class="dot red"></span>
<span class="dot yellow"></span>
<span class="dot green"></span>
<span class="dot red" />
<span class="dot yellow" />
<span class="dot green" />
</div>
</div>
<div class="webpage-content">
<h1>{{ title }}</h1>
<p :style="{ color: paragraphColor }">欢迎光临</p>
<p :style="{ color: paragraphColor }">
欢迎光临
</p>
<ul>
<li v-for="(item, index) in items" :key="index">{{ item }}</li>
<li
v-for="(item, index) in items"
:key="index"
>
{{ item }}
</li>
</ul>
</div>
</div>
@@ -56,18 +63,28 @@ const removeItem = () => {
<div class="tree-node">
<span class="tag">&lt;body&gt;</span>
<div class="tree-children">
<div class="tree-node" :class="{ 'active': title === 'Hello World!' }">
<div
class="tree-node"
:class="{ 'active': title === 'Hello World!' }"
>
<span class="tag">&lt;h1&gt;</span>
<span class="text">{{ title }}</span>
</div>
<div class="tree-node" :class="{ 'active': paragraphColor === 'red' }">
<div
class="tree-node"
:class="{ 'active': paragraphColor === 'red' }"
>
<span class="tag">&lt;p&gt;</span>
<span class="text">欢迎光临</span>
</div>
<div class="tree-node">
<span class="tag">&lt;ul&gt;</span>
<div class="tree-children">
<div class="tree-node" v-for="(item, index) in items" :key="index">
<div
v-for="(item, index) in items"
:key="index"
class="tree-node"
>
<span class="tag">&lt;li&gt;</span>
<span class="text">{{ item }}</span>
</div>
@@ -81,10 +98,30 @@ const removeItem = () => {
</div>
<div class="controls">
<button @click="modifyTitle" class="btn-primary">修改标题</button>
<button @click="addItem" class="btn-secondary">添加列表项</button>
<button @click="changeColor" class="btn-secondary">改变段落颜色</button>
<button @click="removeItem" class="btn-danger">删除列表项</button>
<button
class="btn-primary"
@click="modifyTitle"
>
修改标题
</button>
<button
class="btn-secondary"
@click="addItem"
>
添加列表项
</button>
<button
class="btn-secondary"
@click="changeColor"
>
改变段落颜色
</button>
<button
class="btn-danger"
@click="removeItem"
>
删除列表项
</button>
</div>
<div class="code-display">
@@ -16,9 +16,9 @@
<button
v-for="tab in tabs"
:key="tab.id"
@click="activeTab = tab.id"
class="tab-btn"
:class="{ active: activeTab === tab.id }"
@click="activeTab = tab.id"
>
{{ tab.label }}
</button>
@@ -26,24 +26,40 @@
<div class="content-area">
<!-- 原始类型 -->
<div v-if="activeTab === 'primitive'" class="primitive-types">
<div
v-if="activeTab === 'primitive'"
class="primitive-types"
>
<div class="type-grid">
<div
v-for="type in primitiveTypes"
:key="type.name"
class="type-card"
@click="selectedType = type"
:class="{ selected: selectedType?.name === type.name }"
@click="selectedType = type"
>
<div class="type-icon">{{ type.icon }}</div>
<div class="type-name">{{ type.name }}</div>
<div class="type-example">{{ type.example }}</div>
<div class="type-icon">
{{ type.icon }}
</div>
<div class="type-name">
{{ type.name }}
</div>
<div class="type-example">
{{ type.example }}
</div>
</div>
</div>
<div v-if="selectedType" class="type-detail">
<div class="detail-title">📝 {{ selectedType.name }} 详细说明</div>
<div class="detail-desc">{{ selectedType.description }}</div>
<div
v-if="selectedType"
class="type-detail"
>
<div class="detail-title">
📝 {{ selectedType.name }} 详细说明
</div>
<div class="detail-desc">
{{ selectedType.description }}
</div>
<div class="detail-note">
<strong>💡 关键特性</strong>{{ selectedType.note }}
</div>
@@ -51,66 +67,130 @@
</div>
<!-- 引用类型 -->
<div v-else-if="activeTab === 'reference'" class="reference-types">
<div
v-else-if="activeTab === 'reference'"
class="reference-types"
>
<div class="comparison-box">
<div class="compare-side">
<div class="side-title">原始类型赋值</div>
<div class="side-title">
原始类型赋值
</div>
<div class="code-example">
<div class="code-line">let a = 10</div>
<div class="code-line">let b = a</div>
<div class="code-line">b = 20</div>
<div class="code-line result">// a = 10 (不变)</div>
<div class="code-line">
let a = 10
</div>
<div class="code-line">
let b = a
</div>
<div class="code-line">
b = 20
</div>
<div class="code-line result">
// a = 10 (不变)
</div>
</div>
<div class="visual-box">
<div class="value-box">a = 10</div>
<div class="arrow">复制</div>
<div class="value-box">b = 20</div>
<div class="value-box">
a = 10
</div>
<div class="arrow">
复制
</div>
<div class="value-box">
b = 20
</div>
</div>
</div>
<div class="compare-side">
<div class="side-title">引用类型赋值</div>
<div class="side-title">
引用类型赋值
</div>
<div class="code-example">
<div class="code-line">let obj1 = {x: 10}</div>
<div class="code-line">let obj2 = obj1</div>
<div class="code-line">obj2.x = 20</div>
<div class="code-line result">// obj1.x = 20 (变了!)</div>
<div class="code-line">
let obj1 = {x: 10}
</div>
<div class="code-line">
let obj2 = obj1
</div>
<div class="code-line">
obj2.x = 20
</div>
<div class="code-line result">
// obj1.x = 20 (变了!)
</div>
</div>
<div class="visual-box ref-visual">
<div class="ref-boxes">
<div class="ref-var-box">
<div class="ref-var-name">obj1</div>
<div class="ref-var-arrow"></div>
<div class="ref-var-name">
obj1
</div>
<div class="ref-var-arrow">
</div>
</div>
<div class="ref-var-box">
<div class="ref-var-name">obj2</div>
<div class="ref-var-arrow"></div>
<div class="ref-var-name">
obj2
</div>
<div class="ref-var-arrow">
</div>
</div>
</div>
<div class="arrow down-arrow">指向同一位置</div>
<div class="memory-box">{x: 20}</div>
<div class="arrow down-arrow">
指向同一位置
</div>
<div class="memory-box">
{x: 20}
</div>
</div>
</div>
</div>
<div class="ref-types-list">
<div class="ref-type-item" v-for="type in referenceTypes" :key="type.name">
<div class="ref-icon">{{ type.icon }}</div>
<div
v-for="type in referenceTypes"
:key="type.name"
class="ref-type-item"
>
<div class="ref-icon">
{{ type.icon }}
</div>
<div class="ref-info">
<div class="ref-name">{{ type.name }}</div>
<div class="ref-desc">{{ type.description }}</div>
<div class="ref-name">
{{ type.name }}
</div>
<div class="ref-desc">
{{ type.description }}
</div>
</div>
</div>
</div>
</div>
<!-- 类型转换 -->
<div v-else class="type-conversion">
<div
v-else
class="type-conversion"
>
<div class="conversion-playground">
<div class="input-section">
<label>输入一个值</label>
<input v-model="inputValue" type="text" placeholder="试试输入 '123' 或 'hello'" @keyup.enter="convertType" />
<button @click="convertType" class="convert-btn">转换</button>
<input
v-model="inputValue"
type="text"
placeholder="试试输入 '123' 或 'hello'"
@keyup.enter="convertType"
>
<button
class="convert-btn"
@click="convertType"
>
转换
</button>
</div>
<div class="results-section">
@@ -120,7 +200,10 @@
</div>
<div class="result-row">
<span class="result-label">Number():</span>
<span class="result-value" :class="{ error: conversionResults.number === 'NaN' }">
<span
class="result-value"
:class="{ error: conversionResults.number === 'NaN' }"
>
{{ conversionResults.number }}
</span>
</div>
@@ -131,11 +214,19 @@
</div>
<div class="falsy-values">
<div class="falsy-title"> 转成 false 的值falsy values</div>
<div class="falsy-list">
<span v-for="val in falsyValues" :key="val" class="falsy-item">{{ val }}</span>
<div class="falsy-title">
转成 false 的值falsy values
</div>
<div class="falsy-list">
<span
v-for="val in falsyValues"
:key="val"
class="falsy-item"
>{{ val }}</span>
</div>
<div class="falsy-note">
其他所有值包括空数组 []空对象 {}都转成 true
</div>
<div class="falsy-note">其他所有值包括空数组 []空对象 {}都转成 true</div>
</div>
</div>
</div>
@@ -41,11 +41,19 @@ const currentCode = ref(`const calculatePrice = (price, discount) => {
<div class="input-group">
<label>
价格:
<input v-model.number="price" type="number" min="0" :disabled="isRunning" />
<input
v-model.number="price"
type="number"
min="0"
:disabled="isRunning"
>
</label>
<label>
折扣:
<select v-model.number="discount" :disabled="isRunning">
<select
v-model.number="discount"
:disabled="isRunning"
>
<option :value="0.8">8 (0.8)</option>
<option :value="0.5">5 (0.5)</option>
<option :value="0.7">7 (0.7)</option>
@@ -58,7 +66,9 @@ const currentCode = ref(`const calculatePrice = (price, discount) => {
<div class="pipeline-section machine-section">
<h4>函数</h4>
<div class="machine">
<div class="machine-label">calculatePrice</div>
<div class="machine-label">
calculatePrice
</div>
<div class="machine-code">
<pre v-if="functionType === 'declaration'"><code>return price * discount</code></pre>
<pre v-else-if="functionType === 'expression'"><code>return price * discount</code></pre>
@@ -70,28 +80,50 @@ const currentCode = ref(`const calculatePrice = (price, discount) => {
<button
v-for="type in functionTypes"
:key="type.value"
@click="functionType = type.value"
:class="{ active: functionType === type.value }"
class="type-btn"
@click="functionType = type.value"
>
{{ type.label }}
</button>
</div>
<div class="tip" v-if="functionType !== 'arrow'"> 写法不同但做的事一模一样</div>
<div
v-if="functionType !== 'arrow'"
class="tip"
>
写法不同但做的事一模一样
</div>
</div>
<!-- 输出区 -->
<div class="pipeline-section output-section">
<h4>返回值输出</h4>
<div class="output-display" :class="{ 'processing': isRunning }">
<div v-if="result === null" class="placeholder">?</div>
<div v-else class="result">¥{{ result.toFixed(2) }}</div>
<div
class="output-display"
:class="{ 'processing': isRunning }"
>
<div
v-if="result === null"
class="placeholder"
>
?
</div>
<div
v-else
class="result"
>
¥{{ result.toFixed(2) }}
</div>
</div>
</div>
</div>
<div class="controls">
<button @click="execute" :disabled="isRunning" class="btn-execute">
<button
:disabled="isRunning"
class="btn-execute"
@click="execute"
>
{{ isRunning ? '处理中...' : '执行 ▶' }}
</button>
</div>
@@ -91,9 +91,18 @@ const stop = () => {
'processed': currentStep > index
}"
>
<div class="item-index">{{ item.id }}</div>
<div class="item-code">{{ item.code }}</div>
<div v-if="currentStep === index" class="executing">执行中</div>
<div class="item-index">
{{ item.id }}
</div>
<div class="item-code">
{{ item.code }}
</div>
<div
v-if="currentStep === index"
class="executing"
>
执行中
</div>
</div>
</div>
</div>
@@ -102,11 +111,16 @@ const stop = () => {
<div class="worker-section">
<h4>工位单线程</h4>
<div class="worker">
<div class="worker-emoji">👨💻</div>
<div class="worker-emoji">
👨💻
</div>
<div class="worker-status">
{{ currentStep < steps.length ? '正在执行' : '执行完成' }}
</div>
<div v-if="currentStep < steps.length" class="current-task">
<div
v-if="currentStep < steps.length"
class="current-task"
>
{{ steps[currentStep]?.description }}
</div>
</div>
@@ -122,12 +136,17 @@ const stop = () => {
class="task-item"
:class="{ 'ready': task.status === 'ready' }"
>
<div class="task-code">{{ task.code }}</div>
<div class="task-code">
{{ task.code }}
</div>
<div class="task-status">
{{ task.status === 'ready' ? '✅ 就绪' : '⏳ 等待中...' }}
</div>
</div>
<div v-if="taskQueue.length === 0" class="empty-queue">
<div
v-if="taskQueue.length === 0"
class="empty-queue"
>
暂无待办任务
</div>
</div>
@@ -138,7 +157,12 @@ const stop = () => {
<div class="output-section">
<h4>输出日志</h4>
<div class="output-log">
<div v-if="outputLog.length === 0" class="empty-log">等待输出...</div>
<div
v-if="outputLog.length === 0"
class="empty-log"
>
等待输出...
</div>
<div
v-for="(log, index) in outputLog"
:key="index"
@@ -152,16 +176,31 @@ const stop = () => {
<!-- 控制按钮 -->
<div class="controls">
<button @click="play" :disabled="isPlaying || currentStep >= steps.length" class="btn-play">
<button
:disabled="isPlaying || currentStep >= steps.length"
class="btn-play"
@click="play"
>
{{ isPlaying ? '执行中...' : '▶ 自动播放' }}
</button>
<button @click="nextStep" :disabled="isPlaying || currentStep >= steps.length" class="btn-step">
<button
:disabled="isPlaying || currentStep >= steps.length"
class="btn-step"
@click="nextStep"
>
单步执行
</button>
<button @click="stop" :disabled="!isPlaying" class="btn-stop">
<button
:disabled="!isPlaying"
class="btn-stop"
@click="stop"
>
停止
</button>
<button @click="reset" class="btn-reset">
<button
class="btn-reset"
@click="reset"
>
🔄 重置
</button>
</div>
@@ -170,7 +209,9 @@ const stop = () => {
<div class="explanation">
<p><strong>执行顺序</strong>{{ outputLog.map(l => l.output).join(', ') || '还未开始' }}</p>
<p><strong>代码书写顺序</strong>1, 2, 3, 4, 5</p>
<p class="highlight">代码从上到下写的但执行顺序不一定从上到下因为异步操作会被"推迟"到当前代码执行完之后</p>
<p class="highlight">
代码从上到下写的但执行顺序不一定从上到下因为异步操作会被"推迟"到当前代码执行完之后
</p>
</div>
</div>
</template>
@@ -16,61 +16,126 @@
<button
v-for="tab in tabs"
:key="tab.id"
@click="activeTab = tab.id"
class="tab-btn"
:class="{ active: activeTab === tab.id }"
@click="activeTab = tab.id"
>
{{ tab.label }}
</button>
</div>
<!-- 原型基础 -->
<div v-if="activeTab === 'basic'" class="tab-content">
<div
v-if="activeTab === 'basic'"
class="tab-content"
>
<div class="concept-explanation">
<div class="code-panel">
<div class="code-title">创建对象的方式</div>
<div class="code-title">
创建对象的方式
</div>
<div class="code-block">
<div class="code-line comment">// 方式 1:对象字面量</div>
<div class="code-line">const obj1 = { name: "对象1" }</div>
<div class="code-line">obj1.__proto__ === Object.prototype <span class="comment">// true</span></div>
<div class="code-line"></div>
<div class="code-line comment">// 方式 2:构造函数</div>
<div class="code-line">function Person(name) {</div>
<div class="code-line indent">this.name = name</div>
<div class="code-line">}</div>
<div class="code-line">const p = new Person("张三")</div>
<div class="code-line">p.__proto__ === Person.prototype <span class="comment">// true</span></div>
<div class="code-line comment">
// 方式 1:对象字面量
</div>
<div class="code-line">
const obj1 = { name: "对象1" }
</div>
<div class="code-line">
obj1.__proto__ === Object.prototype <span class="comment">// true</span>
</div>
<div class="code-line" />
<div class="code-line comment">
// 方式 2:构造函数
</div>
<div class="code-line">
function Person(name) {
</div>
<div class="code-line indent">
this.name = name
</div>
<div class="code-line">
}
</div>
<div class="code-line">
const p = new Person("张三")
</div>
<div class="code-line">
p.__proto__ === Person.prototype <span class="comment">// true</span>
</div>
</div>
</div>
<div class="prototype-visual">
<div class="prototype-chain">
<div class="chain-node" :class="{ active: chainLevel >= 0 }" @click="chainLevel = 0">
<div class="node-title">对象实例 (p)</div>
<div
class="chain-node"
:class="{ active: chainLevel >= 0 }"
@click="chainLevel = 0"
>
<div class="node-title">
对象实例 (p)
</div>
<div class="node-content">
<div class="property">name: "张三"</div>
<div class="proto-link">__proto__ </div>
<div class="property">
name: "张三"
</div>
<div class="proto-link">
__proto__
</div>
</div>
</div>
<div class="chain-arrow" v-if="chainLevel >= 0"> 查找</div>
<div
v-if="chainLevel >= 0"
class="chain-arrow"
>
查找
</div>
<div class="chain-node constructor" :class="{ active: chainLevel >= 1 }" @click="chainLevel = 1">
<div class="node-title">Person.prototype</div>
<div
class="chain-node constructor"
:class="{ active: chainLevel >= 1 }"
@click="chainLevel = 1"
>
<div class="node-title">
Person.prototype
</div>
<div class="node-content">
<div class="method">constructor: Person</div>
<div class="proto-link">__proto__ </div>
<div class="method">
constructor: Person
</div>
<div class="proto-link">
__proto__
</div>
</div>
</div>
<div class="chain-arrow" v-if="chainLevel >= 1"> 查找</div>
<div
v-if="chainLevel >= 1"
class="chain-arrow"
>
查找
</div>
<div class="chain-node object" :class="{ active: chainLevel >= 2 }" @click="chainLevel = 2">
<div class="node-title">Object.prototype</div>
<div
class="chain-node object"
:class="{ active: chainLevel >= 2 }"
@click="chainLevel = 2"
>
<div class="node-title">
Object.prototype
</div>
<div class="node-content">
<div class="method">toString()</div>
<div class="method">hasOwnProperty()</div>
<div class="proto-link">__proto__ null</div>
<div class="method">
toString()
</div>
<div class="method">
hasOwnProperty()
</div>
<div class="proto-link">
__proto__ null
</div>
</div>
</div>
</div>
@@ -94,75 +159,149 @@
</div>
<!-- 原型继承 -->
<div v-else-if="activeTab === 'inheritance'" class="tab-content">
<div
v-else-if="activeTab === 'inheritance'"
class="tab-content"
>
<div class="inheritance-demo">
<div class="inheritance-code">
<div class="code-title">原型继承示例</div>
<div class="code-title">
原型继承示例
</div>
<div class="code-block">
<div class="code-line comment">// 父类构造函数</div>
<div class="code-line">function Animal(name) {</div>
<div class="code-line indent">this.name = name</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line">Animal.prototype.eat = function() {</div>
<div class="code-line indent">return this.name + " 在吃东西"</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line comment">// 子类构造函数</div>
<div class="code-line">function Dog(name, breed) {</div>
<div class="code-line indent">Animal.call(this, name) <span class="comment">// 继承属性</span></div>
<div class="code-line indent">this.breed = breed</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line comment">// 继承方法</div>
<div class="code-line">Dog.prototype = Object.create(Animal.prototype)</div>
<div class="code-line">Dog.prototype.constructor = Dog</div>
<div class="code-line comment">
// 父类构造函数
</div>
<div class="code-line">
function Animal(name) {
</div>
<div class="code-line indent">
this.name = name
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line">
Animal.prototype.eat = function() {
</div>
<div class="code-line indent">
return this.name + " 在吃东西"
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line comment">
// 子类构造函数
</div>
<div class="code-line">
function Dog(name, breed) {
</div>
<div class="code-line indent">
Animal.call(this, name) <span class="comment">// 继承属性</span>
</div>
<div class="code-line indent">
this.breed = breed
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line comment">
// 继承方法
</div>
<div class="code-line">
Dog.prototype = Object.create(Animal.prototype)
</div>
<div class="code-line">
Dog.prototype.constructor = Dog
</div>
</div>
</div>
<div class="inheritance-visual">
<div class="class-diagram">
<div class="class-box parent">
<div class="class-title">Animal (父类)</div>
<div class="class-title">
Animal (父类)
</div>
<div class="class-content">
<div class="class-section">
<div class="section-title">属性</div>
<div class="section-item">name: String</div>
<div class="section-title">
属性
</div>
<div class="section-item">
name: String
</div>
</div>
<div class="class-section">
<div class="section-title">方法 (prototype)</div>
<div class="section-item">eat()</div>
<div class="section-title">
方法 (prototype)
</div>
<div class="section-item">
eat()
</div>
</div>
</div>
</div>
<div class="inherit-arrow"> 继承</div>
<div class="inherit-arrow">
继承
</div>
<div class="class-box child">
<div class="class-title">Dog (子类)</div>
<div class="class-title">
Dog (子类)
</div>
<div class="class-content">
<div class="class-section">
<div class="section-title">属性</div>
<div class="section-item">name: String</div>
<div class="section-item">breed: String</div>
<div class="section-title">
属性
</div>
<div class="section-item">
name: String
</div>
<div class="section-item">
breed: String
</div>
</div>
<div class="class-section">
<div class="section-title">方法 (prototype)</div>
<div class="section-item">eat() <span class="inherited">[继承]</span></div>
<div class="section-item">bark() <span class="own">[新增]</span></div>
<div class="section-title">
方法 (prototype)
</div>
<div class="section-item">
eat() <span class="inherited">[继承]</span>
</div>
<div class="section-item">
bark() <span class="own">[新增]</span>
</div>
</div>
</div>
</div>
</div>
<div class="inheritance-playground">
<div class="playground-title">试试创建实例</div>
<div class="input-group">
<input v-model="dogName" placeholder="狗狗名字" />
<input v-model="dogBreed" placeholder="品种" />
<button @click="createDog">创建</button>
<div class="playground-title">
试试创建实例
</div>
<div v-if="dogInstance" class="instance-result">
<div class="input-group">
<input
v-model="dogName"
placeholder="狗狗名字"
>
<input
v-model="dogBreed"
placeholder="品种"
>
<button @click="createDog">
创建
</button>
</div>
<div
v-if="dogInstance"
class="instance-result"
>
<div class="result-item">
<span class="label">名字</span>
<span class="value">{{ dogInstance.name }}</span>
@@ -173,8 +312,16 @@
</div>
<div class="result-item">
<span class="label">调用 eat()</span>
<button @click="callEat" class="action-btn">调用</button>
<span v-if="eatResult" class="method-result">{{ eatResult }}</span>
<button
class="action-btn"
@click="callEat"
>
调用
</button>
<span
v-if="eatResult"
class="method-result"
>{{ eatResult }}</span>
</div>
</div>
</div>
@@ -183,90 +330,185 @@
</div>
<!-- class 语法 -->
<div v-else class="tab-content">
<div
v-else
class="tab-content"
>
<div class="class-syntax-demo">
<div class="syntax-comparison">
<div class="syntax-panel old">
<div class="panel-title">ES5 构造函数</div>
<div class="panel-title">
ES5 构造函数
</div>
<div class="code-block">
<div class="code-line">function Person(name) {</div>
<div class="code-line indent">this.name = name</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line">Person.prototype.greet = function() {</div>
<div class="code-line indent">return "你好,我是" + this.name</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line">const p = new Person("小明")</div>
<div class="code-line">
function Person(name) {
</div>
<div class="code-line indent">
this.name = name
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line">
Person.prototype.greet = function() {
</div>
<div class="code-line indent">
return "你好,我是" + this.name
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line">
const p = new Person("小明")
</div>
</div>
</div>
<div class="syntax-panel new">
<div class="panel-title">ES6 class 语法</div>
<div class="panel-title">
ES6 class 语法
</div>
<div class="code-block">
<div class="code-line">class Person {</div>
<div class="code-line indent">constructor(name) {</div>
<div class="code-line indent indent">this.name = name</div>
<div class="code-line indent">}</div>
<div class="code-line"></div>
<div class="code-line indent">greet() {</div>
<div class="code-line indent indent">return "你好,我是" + this.name</div>
<div class="code-line indent">}</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line">const p = new Person("小明")</div>
<div class="code-line">
class Person {
</div>
<div class="code-line indent">
constructor(name) {
</div>
<div class="code-line indent indent">
this.name = name
</div>
<div class="code-line indent">
}
</div>
<div class="code-line" />
<div class="code-line indent">
greet() {
</div>
<div class="code-line indent indent">
return "你好,我是" + this.name
</div>
<div class="code-line indent">
}
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line">
const p = new Person("小明")
</div>
</div>
</div>
</div>
<div class="class-features">
<div class="feature-card">
<div class="feature-icon">🎯</div>
<div class="feature-title">更清晰的语法</div>
<div class="feature-desc">class 语法让面向对象编程更直观但本质还是基于原型</div>
<div class="feature-icon">
🎯
</div>
<div class="feature-title">
更清晰的语法
</div>
<div class="feature-desc">
class 语法让面向对象编程更直观但本质还是基于原型
</div>
</div>
<div class="feature-card">
<div class="feature-icon">🔗</div>
<div class="feature-title">继承更简单</div>
<div class="feature-desc">使用 extends 关键字实现继承代码更简洁</div>
<div class="feature-icon">
🔗
</div>
<div class="feature-title">
继承更简单
</div>
<div class="feature-desc">
使用 extends 关键字实现继承代码更简洁
</div>
</div>
<div class="feature-card">
<div class="feature-icon"></div>
<div class="feature-title">注意</div>
<div class="feature-desc">class 只是语法糖底层仍然是原型链机制</div>
<div class="feature-icon">
</div>
<div class="feature-title">
注意
</div>
<div class="feature-desc">
class 只是语法糖底层仍然是原型链机制
</div>
</div>
</div>
<div class="inheritance-example">
<div class="code-title">class 继承示例</div>
<div class="code-title">
class 继承示例
</div>
<div class="code-block">
<div class="code-line">class Animal {</div>
<div class="code-line indent">constructor(name) {</div>
<div class="code-line indent indent">this.name = name</div>
<div class="code-line indent">}</div>
<div class="code-line indent">eat() {</div>
<div class="code-line indent indent">return this.name + " 在吃东西"</div>
<div class="code-line indent">}</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line">class Dog extends Animal {</div>
<div class="code-line indent">constructor(name, breed) {</div>
<div class="code-line indent indent">super(name) <span class="comment">// 调用父类构造函数</span></div>
<div class="code-line indent indent">this.breed = breed</div>
<div class="code-line indent">}</div>
<div class="code-line indent">bark() {</div>
<div class="code-line indent indent">return "汪汪!"</div>
<div class="code-line indent">}</div>
<div class="code-line">}</div>
<div class="code-line">
class Animal {
</div>
<div class="code-line indent">
constructor(name) {
</div>
<div class="code-line indent indent">
this.name = name
</div>
<div class="code-line indent">
}
</div>
<div class="code-line indent">
eat() {
</div>
<div class="code-line indent indent">
return this.name + " 在吃东西"
</div>
<div class="code-line indent">
}
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line">
class Dog extends Animal {
</div>
<div class="code-line indent">
constructor(name, breed) {
</div>
<div class="code-line indent indent">
super(name) <span class="comment">// 调用父类构造函数</span>
</div>
<div class="code-line indent indent">
this.breed = breed
</div>
<div class="code-line indent">
}
</div>
<div class="code-line indent">
bark() {
</div>
<div class="code-line indent indent">
return "汪汪!"
</div>
<div class="code-line indent">
}
</div>
<div class="code-line">
}
</div>
</div>
</div>
</div>
</div>
<div class="key-points">
<div class="point-title">🎯 核心要点</div>
<div class="point-title">
🎯 核心要点
</div>
<ul class="point-list">
<li>每个对象都有 <code>__proto__</code> 属性指向其构造函数的 <code>prototype</code></li>
<li>访问对象属性时先在自身查找找不到就沿着原型链向上查找</li>
@@ -20,82 +20,162 @@ const refReset = () => { refStep.value = 0; objData.value.age = 25 }
<template>
<div class="reference-demo">
<div class="demo-title">🔄 vs 引用</div>
<div class="demo-title">
🔄 vs 引用
</div>
<div class="compare-grid">
<!-- 左侧基本类型 -->
<div class="compare-box">
<div class="box-header blue">基本类型复制值</div>
<div class="box-header blue">
基本类型复制值
</div>
<div class="memory-area">
<div class="vars-row">
<div class="var-item" :class="{ active: basicStep >= 0 }">
<div
class="var-item"
:class="{ active: basicStep >= 0 }"
>
<span class="var-label">a</span>
<span class="var-val">{{ basicA }}</span>
</div>
<div class="var-item" :class="{ active: basicStep >= 1, changed: basicStep >= 2 }">
<div
class="var-item"
:class="{ active: basicStep >= 1, changed: basicStep >= 2 }"
>
<span class="var-label">b</span>
<span class="var-val">{{ basicB ?? '?' }}</span>
</div>
</div>
<div class="copy-arrow" v-if="basicStep >= 1"> 复制值</div>
<div
v-if="basicStep >= 1"
class="copy-arrow"
>
复制值
</div>
</div>
<div class="result-text" :class="basicStep === 2 ? 'success' : 'info'">
<div
class="result-text"
:class="basicStep === 2 ? 'success' : 'info'"
>
{{ basicStep === 0 ? '点击复制' : basicStep === 1 ? 'b 得到 10' : '✅ 修改 b 不影响 a' }}
</div>
<div class="btn-group">
<button @click="basicCopy" :disabled="basicStep >= 1">复制</button>
<button @click="basicModify" :disabled="basicStep !== 1"> b</button>
<button @click="basicReset" class="reset">重置</button>
<button
:disabled="basicStep >= 1"
@click="basicCopy"
>
复制
</button>
<button
:disabled="basicStep !== 1"
@click="basicModify"
>
b
</button>
<button
class="reset"
@click="basicReset"
>
重置
</button>
</div>
</div>
<!-- 右侧引用类型 -->
<div class="compare-box">
<div class="box-header orange">引用类型复制地址</div>
<div class="box-header orange">
引用类型复制地址
</div>
<div class="memory-area">
<div class="vars-row">
<div class="var-item" :class="{ active: refStep >= 0 }">
<div
class="var-item"
:class="{ active: refStep >= 0 }"
>
<span class="var-label">obj1</span>
<span class="var-addr">0x001</span>
</div>
<div class="var-item" :class="{ active: refStep >= 1 }">
<div
class="var-item"
:class="{ active: refStep >= 1 }"
>
<span class="var-label">obj2</span>
<span class="var-addr">{{ refStep >= 1 ? '0x001' : '?' }}</span>
</div>
</div>
<div class="data-box" :class="{ changed: refStep === 2, copied: refStep === 3 }">
<div class="data-addr">0x001</div>
<div class="data-content">{ age: {{ objData.age }} }</div>
<div
class="data-box"
:class="{ changed: refStep === 2, copied: refStep === 3 }"
>
<div class="data-addr">
0x001
</div>
<div class="data-content">
{ age: {{ objData.age }} }
</div>
</div>
<div
v-if="refStep >= 1"
class="copy-arrow"
>
指向同一地址
</div>
<div class="copy-arrow" v-if="refStep >= 1">指向同一地址</div>
</div>
<div class="result-text" :class="refStep === 2 ? 'warning' : refStep === 3 ? 'success' : 'info'">
<div
class="result-text"
:class="refStep === 2 ? 'warning' : refStep === 3 ? 'success' : 'info'"
>
{{ refStep === 0 ? '点击复制' : refStep === 1 ? '共享地址' : refStep === 2 ? '⚠️ 一改全变' : '✅ 已分离' }}
</div>
<div class="btn-group">
<button @click="refCopy" :disabled="refStep >= 1">复制</button>
<button @click="refModify" :disabled="refStep !== 1">修改</button>
<button @click="refSpread" :disabled="refStep !== 2">展开</button>
<button @click="refReset" class="reset">重置</button>
<button
:disabled="refStep >= 1"
@click="refCopy"
>
复制
</button>
<button
:disabled="refStep !== 1"
@click="refModify"
>
修改
</button>
<button
:disabled="refStep !== 2"
@click="refSpread"
>
展开
</button>
<button
class="reset"
@click="refReset"
>
重置
</button>
</div>
</div>
</div>
<div class="code-compare">
<div class="code-col">
<div class="code-title">基本类型</div>
<div class="code-title">
基本类型
</div>
<pre><code>let a = 10
let b = a // b=10
b = 20 // a还是10</code></pre>
</div>
<div class="code-col">
<div class="code-title">引用类型</div>
<div class="code-title">
引用类型
</div>
<pre><code>let obj1 = {age:25}
let obj2 = obj1
obj2.age=30 // obj1也变了!
@@ -52,10 +52,10 @@ updateExplanation()
<button
v-for="scope in scopes"
:key="scope.id"
@click="activeScope = scope.id; updateExplanation()"
class="scope-btn"
:class="{ active: activeScope === scope.id }"
:style="{ borderColor: scope.color }"
@click="activeScope = scope.id; updateExplanation()"
>
{{ scope.name }}
</button>
@@ -71,7 +71,10 @@ updateExplanation()
:class="{ active: activeScope === scope.id, dimmed: activeScope !== scope.id }"
:style="{ borderLeftColor: scope.color }"
>
<div class="level-header" :style="{ color: scope.color }">
<div
class="level-header"
:style="{ color: scope.color }"
>
{{ scope.name }}
</div>
<div class="level-vars">
@@ -83,7 +86,10 @@ updateExplanation()
>
<span class="var-name">{{ v.name }}</span>
<span class="var-value">= {{ v.value }}</span>
<span v-if="!v.own" class="var-from"> {{ v.from }}</span>
<span
v-if="!v.own"
class="var-from"
> {{ v.from }}</span>
</div>
</div>
</div>
@@ -91,8 +97,12 @@ updateExplanation()
<!-- 说明 -->
<div class="explanation-box">
<div class="explanation-title">💡 当前位置可见的变量</div>
<div class="explanation-text">{{ explanation }}</div>
<div class="explanation-title">
💡 当前位置可见的变量
</div>
<div class="explanation-text">
{{ explanation }}
</div>
</div>
</div>
@@ -16,89 +16,148 @@
<button
v-for="scenario in scenarios"
:key="scenario.id"
@click="activeScenario = scenario.id"
class="scenario-btn"
:class="{ active: activeScenario === scenario.id }"
@click="activeScenario = scenario.id"
>
{{ scenario.label }}
</button>
</div>
<!-- 方法调用 -->
<div v-if="activeScenario === 'method'" class="scenario-content">
<div
v-if="activeScenario === 'method'"
class="scenario-content"
>
<div class="split-view">
<div class="code-panel">
<div class="code-title">对象方法调用</div>
<div class="code-title">
对象方法调用
</div>
<div class="code-block">
<div class="code-line">const person = {</div>
<div class="code-line indent">name: "张三",</div>
<div class="code-line indent">greet: function() {</div>
<div class="code-line indent indent">return "你好,我是" + this.name</div>
<div class="code-line indent">}</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line">person.greet() <span class="comment">// this → person</span></div>
<div class="code-line">
const person = {
</div>
<div class="code-line indent">
name: "张三",
</div>
<div class="code-line indent">
greet: function() {
</div>
<div class="code-line indent indent">
return "你好,我是" + this.name
</div>
<div class="code-line indent">
}
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line">
person.greet() <span class="comment">// this → person</span>
</div>
</div>
</div>
<div class="visual-panel">
<div class="object-visual">
<div class="object-box">
<div class="object-title">person 对象</div>
<div class="object-title">
person 对象
</div>
<div class="object-content">
<div class="property">name: "张三"</div>
<div class="method" @click="simulateMethodCall">
<div class="property">
name: "张三"
</div>
<div
class="method"
@click="simulateMethodCall"
>
greet: function() { ... }
</div>
</div>
</div>
<div class="arrow-indicator">
<div class="this-pointer">this </div>
<div class="this-pointer">
this
</div>
</div>
<div v-if="methodCallResult" class="result-box">
<div
v-if="methodCallResult"
class="result-box"
>
{{ methodCallResult }}
</div>
</div>
<div class="rule-box">
<div class="rule-title">规则对象方法</div>
<div class="rule-content">通过对象调用方法时<code>this</code> 指向该对象</div>
<div class="rule-title">
规则对象方法
</div>
<div class="rule-content">
通过对象调用方法时<code>this</code> 指向该对象
</div>
</div>
</div>
</div>
</div>
<!-- 普通函数 -->
<div v-else-if="activeScenario === 'function'" class="scenario-content">
<div
v-else-if="activeScenario === 'function'"
class="scenario-content"
>
<div class="split-view">
<div class="code-panel">
<div class="code-title">普通函数调用</div>
<div class="code-title">
普通函数调用
</div>
<div class="code-block">
<div class="code-line">function show() {</div>
<div class="code-line indent">return this === window</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line">show() <span class="comment">// this → window (浏览器)</span></div>
<div class="code-line"></div>
<div class="code-line comment">// 严格模式下是 undefined</div>
<div class="code-line">
function show() {
</div>
<div class="code-line indent">
return this === window
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line">
show() <span class="comment">// this → window (浏览器)</span>
</div>
<div class="code-line" />
<div class="code-line comment">
// 严格模式下是 undefined
</div>
</div>
</div>
<div class="visual-panel">
<div class="function-visual">
<div class="global-window">
<div class="window-title">window (全局对象)</div>
<div class="window-title">
window (全局对象)
</div>
<div class="window-content">
<div class="global-item">show 函数在这里</div>
<div class="global-item">this window</div>
<div class="global-item">
show 函数在这里
</div>
<div class="global-item">
this window
</div>
</div>
</div>
</div>
<div class="mode-toggle">
<button @click="strictMode = !strictMode" class="toggle-btn">
<button
class="toggle-btn"
@click="strictMode = !strictMode"
>
{{ strictMode ? '严格模式:开' : '严格模式:关' }}
</button>
<div class="mode-result">
@@ -107,7 +166,9 @@
</div>
<div class="rule-box">
<div class="rule-title">规则普通函数</div>
<div class="rule-title">
规则普通函数
</div>
<div class="rule-content">
非严格模式<code>this</code> 指向全局对象<br>
严格模式<code>this</code> <code>undefined</code>
@@ -118,20 +179,39 @@
</div>
<!-- 构造函数 -->
<div v-else-if="activeScenario === 'constructor'" class="scenario-content">
<div
v-else-if="activeScenario === 'constructor'"
class="scenario-content"
>
<div class="split-view">
<div class="code-panel">
<div class="code-title">构造函数调用</div>
<div class="code-title">
构造函数调用
</div>
<div class="code-block">
<div class="code-line">function Person(name) {</div>
<div class="code-line indent">this.name = name</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line">const p1 = new Person("李四")</div>
<div class="code-line">const p2 = new Person("王五")</div>
<div class="code-line"></div>
<div class="code-line comment">// p1.name = "李四"</div>
<div class="code-line comment">// p2.name = "王五"</div>
<div class="code-line">
function Person(name) {
</div>
<div class="code-line indent">
this.name = name
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line">
const p1 = new Person("李四")
</div>
<div class="code-line">
const p2 = new Person("王五")
</div>
<div class="code-line" />
<div class="code-line comment">
// p1.name = "李四"
</div>
<div class="code-line comment">
// p2.name = "王五"
</div>
</div>
</div>
@@ -142,17 +222,23 @@
<span class="step-num">1</span>
<span>创建新对象</span>
</div>
<div class="process-arrow"></div>
<div class="process-arrow">
</div>
<div class="process-step">
<span class="step-num">2</span>
<span>this 指向新对象</span>
</div>
<div class="process-arrow"></div>
<div class="process-arrow">
</div>
<div class="process-step">
<span class="step-num">3</span>
<span>执行构造函数</span>
</div>
<div class="process-arrow"></div>
<div class="process-arrow">
</div>
<div class="process-step">
<span class="step-num">4</span>
<span>返回新对象</span>
@@ -161,18 +247,28 @@
<div class="object-comparison">
<div class="obj-instance">
<div class="obj-title">p1</div>
<div class="obj-content">name: "李四"</div>
<div class="obj-title">
p1
</div>
<div class="obj-content">
name: "李四"
</div>
</div>
<div class="obj-instance">
<div class="obj-title">p2</div>
<div class="obj-content">name: "王五"</div>
<div class="obj-title">
p2
</div>
<div class="obj-content">
name: "王五"
</div>
</div>
</div>
</div>
<div class="rule-box">
<div class="rule-title">规则new 调用</div>
<div class="rule-title">
规则new 调用
</div>
<div class="rule-content">
使用 <code>new</code> 调用函数时<code>this</code> 指向新创建的对象
</div>
@@ -182,52 +278,104 @@
</div>
<!-- call/apply/bind -->
<div v-else-if="activeScenario === 'explicit'" class="scenario-content">
<div
v-else-if="activeScenario === 'explicit'"
class="scenario-content"
>
<div class="split-view">
<div class="code-panel">
<div class="code-title">显式绑定 (call/apply/bind)</div>
<div class="code-title">
显式绑定 (call/apply/bind)
</div>
<div class="code-block">
<div class="code-line">function greet() {</div>
<div class="code-line indent">return "我是" + this.name</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line">const person = { name: "小明" }</div>
<div class="code-line"></div>
<div class="code-line">greet.call(person) <span class="comment">// 显式指定 this</span></div>
<div class="code-line">greet.apply(person)</div>
<div class="code-line">const bound = greet.bind(person)</div>
<div class="code-line">
function greet() {
</div>
<div class="code-line indent">
return "我是" + this.name
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line">
const person = { name: "小明" }
</div>
<div class="code-line" />
<div class="code-line">
greet.call(person) <span class="comment">// 显式指定 this</span>
</div>
<div class="code-line">
greet.apply(person)
</div>
<div class="code-line">
const bound = greet.bind(person)
</div>
</div>
</div>
<div class="visual-panel">
<div class="binding-visual">
<div class="function-box">
<div class="box-title">greet 函数</div>
<div class="box-content">this.name</div>
<div class="box-title">
greet 函数
</div>
<div class="box-content">
this.name
</div>
</div>
<div class="binding-methods">
<div class="binding-item" @click="simulateCall" :class="{ active: bindingMethod === 'call' }">
<div class="method-name">call(person)</div>
<div class="method-desc">立即调用this person</div>
<div
class="binding-item"
:class="{ active: bindingMethod === 'call' }"
@click="simulateCall"
>
<div class="method-name">
call(person)
</div>
<div class="method-desc">
立即调用this person
</div>
</div>
<div class="binding-item" @click="simulateApply" :class="{ active: bindingMethod === 'apply' }">
<div class="method-name">apply(person)</div>
<div class="method-desc"> call参数为数组</div>
<div
class="binding-item"
:class="{ active: bindingMethod === 'apply' }"
@click="simulateApply"
>
<div class="method-name">
apply(person)
</div>
<div class="method-desc">
call参数为数组
</div>
</div>
<div class="binding-item" @click="simulateBind" :class="{ active: bindingMethod === 'bind' }">
<div class="method-name">bind(person)</div>
<div class="method-desc">返回新函数this 固定</div>
<div
class="binding-item"
:class="{ active: bindingMethod === 'bind' }"
@click="simulateBind"
>
<div class="method-name">
bind(person)
</div>
<div class="method-desc">
返回新函数this 固定
</div>
</div>
</div>
<div v-if="bindingResult" class="binding-result">
<div
v-if="bindingResult"
class="binding-result"
>
{{ bindingResult }}
</div>
</div>
<div class="rule-box">
<div class="rule-title">规则显式绑定</div>
<div class="rule-title">
规则显式绑定
</div>
<div class="rule-content">
<code>call/apply/bind</code> 可以显式指定 <code>this</code> 的指向
</div>
@@ -237,48 +385,85 @@
</div>
<!-- 箭头函数 -->
<div v-else class="scenario-content">
<div
v-else
class="scenario-content"
>
<div class="split-view">
<div class="code-panel">
<div class="code-title">箭头函数的 this</div>
<div class="code-title">
箭头函数的 this
</div>
<div class="code-block">
<div class="code-line">const person = {</div>
<div class="code-line indent">name: "小红",</div>
<div class="code-line indent">greet: function() {</div>
<div class="code-line indent indent">setTimeout(() => {</div>
<div class="code-line indent indent indent">console.log(this.name)</div>
<div class="code-line indent indent">}, 1000)</div>
<div class="code-line indent">}</div>
<div class="code-line">}</div>
<div class="code-line"></div>
<div class="code-line">person.greet() <span class="comment">// 输出 "小红"</span></div>
<div class="code-line">
const person = {
</div>
<div class="code-line indent">
name: "小红",
</div>
<div class="code-line indent">
greet: function() {
</div>
<div class="code-line indent indent">
setTimeout(() => {
</div>
<div class="code-line indent indent indent">
console.log(this.name)
</div>
<div class="code-line indent indent">
}, 1000)
</div>
<div class="code-line indent">
}
</div>
<div class="code-line">
}
</div>
<div class="code-line" />
<div class="code-line">
person.greet() <span class="comment">// 输出 "小红"</span>
</div>
</div>
</div>
<div class="visual-panel">
<div class="arrow-function-visual">
<div class="outer-context">
<div class="context-title">外层作用域 (person)</div>
<div class="context-title">
外层作用域 (person)
</div>
<div class="context-content">
<div class="context-item">this.name = "小红"</div>
<div class="context-item">
this.name = "小红"
</div>
</div>
</div>
<div class="arrow-capture">
<div class="capture-title">箭头函数捕获外层 this</div>
<div class="capture-arrow"> 继承 this</div>
<div class="capture-title">
箭头函数捕获外层 this
</div>
<div class="capture-arrow">
继承 this
</div>
</div>
<div class="inner-context">
<div class="context-title">箭头函数内部</div>
<div class="context-title">
箭头函数内部
</div>
<div class="context-content">
<div class="context-item">this 外层的 this</div>
<div class="context-item">
this 外层的 this
</div>
</div>
</div>
</div>
<div class="rule-box">
<div class="rule-title">规则箭头函数</div>
<div class="rule-title">
规则箭头函数
</div>
<div class="rule-content">
箭头函数没有自己的 <code>this</code>它继承外层作用域的 <code>this</code>
</div>
@@ -288,7 +473,9 @@
</div>
<div class="quick-reference">
<div class="reference-title">📋 this 指向速查表</div>
<div class="reference-title">
📋 this 指向速查表
</div>
<div class="reference-table">
<div class="ref-row header">
<span>调用方式</span>
@@ -44,36 +44,85 @@ const reset = () => {
</div>
<div class="boxes-row">
<div class="var-box" :class="{ error: messageType === 'error' }">
<div class="box-tag const">const</div>
<div class="box-name">name</div>
<div class="box-value">{{ name }}</div>
<div class="box-lock">🔒</div>
<div
class="var-box"
:class="{ error: messageType === 'error' }"
>
<div class="box-tag const">
const
</div>
<div class="box-name">
name
</div>
<div class="box-value">
{{ name }}
</div>
<div class="box-lock">
🔒
</div>
</div>
<div class="var-box" :class="{ success: messageType === 'success' }">
<div class="box-tag let">let</div>
<div class="box-name">age</div>
<div class="box-value">{{ age }}</div>
<div class="box-lock">🔓</div>
<div
class="var-box"
:class="{ success: messageType === 'success' }"
>
<div class="box-tag let">
let
</div>
<div class="box-name">
age
</div>
<div class="box-value">
{{ age }}
</div>
<div class="box-lock">
🔓
</div>
</div>
<div class="var-box">
<div class="box-tag const">const</div>
<div class="box-name">isStudent</div>
<div class="box-value">{{ isStudent }}</div>
<div class="box-lock">🔒</div>
<div class="box-tag const">
const
</div>
<div class="box-name">
isStudent
</div>
<div class="box-value">
{{ isStudent }}
</div>
<div class="box-lock">
🔒
</div>
</div>
</div>
<div class="message" v-if="showMessage" :class="messageType">
<div
v-if="showMessage"
class="message"
:class="messageType"
>
{{ showMessage }}
</div>
<div class="controls">
<button @click="modifyAge" class="btn btn-primary">修改 age</button>
<button @click="modifyName" class="btn btn-danger">修改 name</button>
<button @click="reset" class="btn btn-secondary">重置</button>
<button
class="btn btn-primary"
@click="modifyAge"
>
修改 age
</button>
<button
class="btn btn-danger"
@click="modifyName"
>
修改 name
</button>
<button
class="btn btn-secondary"
@click="reset"
>
重置
</button>
</div>
<div class="code-snippet">
@@ -15,32 +15,58 @@
<div class="code-display">
<div class="code-block">
<div class="code-line" v-for="(line, i) in codeLines" :key="i" :class="{ active: currentLine === i }">
<div
v-for="(line, i) in codeLines"
:key="i"
class="code-line"
:class="{ active: currentLine === i }"
>
<span class="line-num">{{ i + 1 }}</span>
<span class="line-code" v-html="highlightCode(line)"></span>
<span
class="line-code"
v-html="highlightCode(line)"
/>
</div>
</div>
<div class="visualization">
<div class="scope-area global-scope">
<div class="scope-title">全局作用域房子外</div>
<div class="scope-title">
全局作用域房子外
</div>
<div class="scope-vars">
<div v-if="step >= 1" class="var-item" :class="{ error: step === 4 }">
<div
v-if="step >= 1"
class="var-item"
:class="{ error: step === 4 }"
>
<span class="var-type">var</span>
<span class="var-name">globalVar</span>
<span class="var-value">= "外面"</span>
</div>
</div>
<div class="scope-area block-scope" v-if="step >= 2">
<div class="scope-title">块级作用域房间内</div>
<div
v-if="step >= 2"
class="scope-area block-scope"
>
<div class="scope-title">
块级作用域房间内
</div>
<div class="scope-vars">
<div v-if="step >= 2" class="var-item" :class="{ error: step === 4 }">
<div
v-if="step >= 2"
class="var-item"
:class="{ error: step === 4 }"
>
<span class="var-type">var</span>
<span class="var-name">blockVar</span>
<span class="var-value">= "房间里"</span>
</div>
<div v-if="step >= 3" class="var-item let">
<div
v-if="step >= 3"
class="var-item let"
>
<span class="var-type">let</span>
<span class="var-name">blockLet</span>
<span class="var-value">= "只有房间内能用"</span>
@@ -50,9 +76,16 @@
</div>
<div class="console-output">
<div class="console-title">控制台输出</div>
<div class="console-title">
控制台输出
</div>
<div class="console-lines">
<div v-for="(output, i) in consoleOutput" :key="i" class="console-line" :class="{ error: output.error }">
<div
v-for="(output, i) in consoleOutput"
:key="i"
class="console-line"
:class="{ error: output.error }"
>
{{ output.text }}
</div>
</div>
@@ -61,10 +94,27 @@
</div>
<div class="controls">
<button @click="prevStep" :disabled="step === 0" class="control-btn"> 上一步</button>
<button
:disabled="step === 0"
class="control-btn"
@click="prevStep"
>
上一步
</button>
<span class="step-indicator">{{ step + 1 }} / {{ maxSteps }}</span>
<button @click="nextStep" :disabled="step === maxSteps" class="control-btn">下一步 </button>
<button @click="reset" class="control-btn secondary">重置</button>
<button
:disabled="step === maxSteps"
class="control-btn"
@click="nextStep"
>
下一步
</button>
<button
class="control-btn secondary"
@click="reset"
>
重置
</button>
</div>
<div class="info-box">