當(dāng)心,這些 JavaScript 坑讓人防不勝防!
JavaScript 作為一門(mén)靈活的編程語(yǔ)言,有著許多令人困惑的特性和行為。即使是經(jīng)驗(yàn)豐富的開(kāi)發(fā)者,有時(shí)也會(huì)掉入這些"陷阱"中,分享一些我遇到的也踩過(guò)的坑。

1. 類(lèi)型轉(zhuǎn)換的迷惑
JavaScript 的類(lèi)型轉(zhuǎn)換規(guī)則可能會(huì)讓人摸不著頭腦:
console.log([] + []); // 輸出:""
console.log([] + {}); // 輸出:"[object Object]"
console.log({} + []); // 輸出:0(在某些瀏覽器中)
console.log([] == ![]); // 輸出:true這些看似不合理的結(jié)果,其實(shí)都遵循著 JavaScript 的類(lèi)型轉(zhuǎn)換規(guī)則。當(dāng)進(jìn)行加法運(yùn)算時(shí),JavaScript 會(huì)優(yōu)先將操作數(shù)轉(zhuǎn)換為原始類(lèi)型,然后進(jìn)行運(yùn)算。
2. 變量提升的陷阱
console.log(a); // 輸出:undefined
var a = 1;
console.log(b); // 報(bào)錯(cuò):ReferenceError
let b = 2;變量提升是 JavaScript 中一個(gè)經(jīng)典的概念。使用 var 聲明的變量會(huì)被提升到作用域頂部,但初始化不會(huì)提升。而 let 和 const 聲明的變量存在暫時(shí)性死區(qū)(TDZ),在聲明前訪問(wèn)會(huì)拋出錯(cuò)誤。
3. this 指向問(wèn)題
const obj = {
    name: '小明',
    sayHi() {
        setTimeout(function() {
            console.log('你好,' + this.name);
        }, 100);
    }
};
obj.sayHi(); // 輸出:你好,undefined在這個(gè)例子中,setTimeout 中的回調(diào)函數(shù)里的 this 指向全局對(duì)象(非嚴(yán)格模式下)或 undefined(嚴(yán)格模式下),而不是 obj。解決方案包括:
// 方案1:使用箭頭函數(shù)
setTimeout(() => {
    console.log('你好,' + this.name);
}, 100);
// 方案2:使用 bind
setTimeout(function() {
    console.log('你好,' + this.name);
}.bind(this), 100);4. 閉包陷阱
for (var i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i);
    }, 100);
}
// 輸出:3, 3, 3這是一個(gè)經(jīng)典的閉包問(wèn)題。使用 var 聲明的變量 i 是函數(shù)作用域的,所有的 setTimeout 回調(diào)都共享同一個(gè) i。解決方案:

5. 數(shù)值計(jì)算精度問(wèn)題
console.log(0.1 + 0.2); // 輸出:0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // 輸出:false這是因?yàn)?JavaScript 使用 IEEE 754 雙精度浮點(diǎn)數(shù)來(lái)表示數(shù)字,某些小數(shù)無(wú)法被精確表示。解決方案:

6. 數(shù)組方法的陷阱

解決方案:

7. Promise 的常見(jiàn)陷阱

正確的做法:

8. 事件監(jiān)聽(tīng)器的內(nèi)存泄漏
// 錯(cuò)誤示例:可能造成內(nèi)存泄漏
function addHandler() {
    const element = document.getElementById('button');
    element.addEventListener('click', () => {
        console.log('Clicked');
    });
}
// 正確示例:
function addHandler() {
    const element = document.getElementById('button');
    const handler = () => {
        console.log('Clicked');
    };
    element.addEventListener('click', handler);
    
    // 清理函數(shù)
    return () => {
        element.removeEventListener('click', handler);
    };
}














 
 
 




 
 
 
 