🚨《你不知道的 JavaScript 真相:99% 的人都误会了这几点!》
JavaScript 是世界上最流行的编程语言之一,但也是误解最多的语言之一。你以为你懂它,其实它远比你想象的复杂。本篇文章带你重新认识 JavaScript,解锁那些你可能忽略、误解、甚至从未听说的核心机制!
🔍 1. var、let 和 const 的真区别不仅仅是块级作用域
很多人会说:“var 是函数作用域,let/const 是块级作用域。”——这句话没错,但远远不够。
❗ 真相一:var 声明的变量会被提升到函数顶部
console.log(foo); // undefined
var foo = 42;
你以为 foo 是“未定义”?其实它被提升了,只是值还没赋。
❗ 真相二:let/const 存在“暂时性死区(TDZ)”
console.log(bar); // ReferenceError!
let bar = 10;
不是没声明,而是你不能在声明之前访问它。
⸻
🧠 2. 闭包到底闭的是什么?不是变量,是作用域链!
闭包是很多人面试的必考题,但你真的理解它的底层逻辑吗?
function outer() {
let a = 1;
return function inner() {
console.log(a);
};
}
这个 inner 函数并不是“复制”了变量 a,而是记住了它当时所处的作用域链。
✅ 闭包 = 函数 + 词法环境(Lexical Environment)
⸻
⚠️ 3. this 真的是 JS 最大的坑之一
你是否经历过这样的灵魂拷问:
const obj = {
name: 'JS',
say: function () {
setTimeout(function () {
console.log(this.name);
}, 1000);
},
};
obj.say(); // ??
很多人以为会打印 “JS”,但其实是 undefined,因为:
• setTimeout 内部的函数,this 指向的是 window(或 global)
✅ 正确做法:
setTimeout(() => {
console.log(this.name); // 箭头函数没有自己的 this
}, 1000);
⸻
📦 4. JavaScript 的异步不是“延迟”,而是“调度”
当你看到 setTimeout(fn, 0),你以为它会立即执行?错!
JS 的执行模型是:
事件循环(Event Loop)+ 任务队列(Task Queue)
任务分两类:
• 宏任务(macro task):setTimeout、setInterval
• 微任务(micro task):Promise.then、MutationObserver
示例:
console.log(1);
setTimeout(() => console.log(2));
Promise.resolve().then(() => console.log(3));
console.log(4);
输出:
1
4
3
2
⸻
🤯 5. 数组的 map/filter 真的“跳过空位”?
const arr = [1, , 3];
arr.map(x => console.log(x));
输出:
1
3
➡️ 空位(hole)不是 undefined,而是根本“不存在”,所以 map 不会执行对应回调。
⸻
📘 结语:你不是真的了解 JavaScript,直到你读懂它的“怪癖”
JavaScript 就像一位戴着笑脸面具的魔术师,看起来简单,其实处处都是套路。如果你真心想成为前端高手,不能只会写,还要懂它的“行为”。
⸻
如果你觉得今天的内容还不错,欢迎 收藏 + 点赞,我会持续更新“你不知道的 JavaScript”系列,深入浅出挖掘那些看似熟悉却被误解的 JS 概念!
🚀 关注我,一起搞懂 JavaScript 的一切细节!