当心,这些 JavaScript 坑让人防不胜防!

开发
JavaScript 作为一门灵活的编程语言,有着许多令人困惑的特性和行为。即使是经验丰富的开发者,有时也会掉入这些"陷阱"中,分享一些我遇到的也踩过的坑。

JavaScript 作为一门灵活的编程语言,有着许多令人困惑的特性和行为。即使是经验丰富的开发者,有时也会掉入这些"陷阱"中,分享一些我遇到的也踩过的坑。

1. 类型转换的迷惑

JavaScript 的类型转换规则可能会让人摸不着头脑:

console.log([] + []); // 输出:""
console.log([] + {}); // 输出:"[object Object]"
console.log({} + []); // 输出:0(在某些浏览器中)
console.log([] == ![]); // 输出:true

这些看似不合理的结果,其实都遵循着 JavaScript 的类型转换规则。当进行加法运算时,JavaScript 会优先将操作数转换为原始类型,然后进行运算。

2. 变量提升的陷阱

console.log(a); // 输出:undefined
var a = 1;

console.log(b); // 报错:ReferenceError
let b = 2;

变量提升是 JavaScript 中一个经典的概念。使用 var 声明的变量会被提升到作用域顶部,但初始化不会提升。而 let 和 const 声明的变量存在暂时性死区(TDZ),在声明前访问会抛出错误。

3. this 指向问题

const obj = {
    name: '小明',
    sayHi() {
        setTimeout(function() {
            console.log('你好,' + this.name);
        }, 100);
    }
};

obj.sayHi(); // 输出:你好,undefined

在这个例子中,setTimeout 中的回调函数里的 this 指向全局对象(非严格模式下)或 undefined(严格模式下),而不是 obj。解决方案包括:

// 方案1:使用箭头函数
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

这是一个经典的闭包问题。使用 var 声明的变量 i 是函数作用域的,所有的 setTimeout 回调都共享同一个 i。解决方案:

5. 数值计算精度问题

console.log(0.1 + 0.2); // 输出:0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // 输出:false

这是因为 JavaScript 使用 IEEE 754 双精度浮点数来表示数字,某些小数无法被精确表示。解决方案:

6. 数组方法的陷阱

解决方案:

7. Promise 的常见陷阱

正确的做法:

8. 事件监听器的内存泄漏

// 错误示例:可能造成内存泄漏
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);
    
    // 清理函数
    return () => {
        element.removeEventListener('click', handler);
    };
}
责任编辑:赵宁宁 来源: JavaScript
相关推荐

2022-04-01 17:32:00

Windows3.1元宇宙模式黑客

2013-05-13 13:53:51

2020-05-06 08:01:39

黑客恶意攻击网络安全

2024-09-10 15:11:12

2010-09-28 09:33:16

2017-01-16 09:20:32

2021-09-13 15:35:14

戴尔

2016-11-04 20:45:07

2011-06-28 14:03:06

2017-03-30 23:06:36

2012-12-09 17:46:27

2013-04-07 15:51:41

2009-03-24 13:37:03

2014-11-24 09:13:38

2021-06-15 10:41:00

数据中毒机器学习网络攻击

2023-03-15 14:24:02

2022-06-22 11:09:21

网络钓鱼网络攻击

2021-10-20 11:52:49

ATM机AI密码

2017-09-11 16:24:47

2018-08-13 20:58:52

点赞
收藏

51CTO技术栈公众号