JavaScript 中的一些奇怪问题

JavaScript 在开发过程中可能会出现很多奇怪的问题,以下是一些示例:

1、变量提升问题:

变量提升是 JavaScript 中一个常见的问题,特别是当没有充分理解变量作用域和声明提升时。以下是一个变量提升导致的问题示例:

var a = 1;
function foo() {
console.log(a);
var a = 2;
}
foo(); // 输出:undefined

预期输出是 1,但实际上输出的是 undefined。这是因为在函数内部声明了一个同名变量 a,函数作用域内的变量声明被提升到了函数开头,所以 console.log(a) 实际上输出的是 undefined。

解决该问题的方法是使用 let 或 const 关键字声明变量,这样可以避免变量提升和作用域污染:

let a = 1;
function foo() {
console.log(a);
let a = 2;
}
foo(); // 输出:报错 Uncaught ReferenceError: Cannot access 'a' before initialization

2、this 指向问题:

this 关键字在 JavaScript 中非常重要,但也很容易导致问题。this 关键字的指向是动态的,它的值取决于函数的调用方式。以下是一个 this 关键字导致的问题示例:

var name = "John";

var person = {
name: "Bob",
sayName: function () {
console.log("name", this.name);
},
}; var sayName = person.sayName; sayName();

预期输出是 "Bob",但实际上输出的是 "John"。这是因为在全局作用域中调用 sayName 函数时,this 指向的是全局对象 window,而全局作用域中定义的 name 变量值为 "John"。

解决该问题的方法是使用 call、apply 或 bind 方法来改变 this 的指向:

sayName.call(person);

3、===== 比较问题:

console.log(false == "0"); // 输出 true
console.log(false === "0"); // 输出 false

在第一行中,"0" 被转换为 false,因此 false == false,结果为 true。在第二行中,使用了严格相等运算符 ===,它不会自动转换类型,因此 false 和 "0" 不相等,结果为 false。

4、循环中的异步问题:

异步操作是 JavaScript 中一个重要的特性,但也容易导致一些问题。以下是一个异步操作导致的问题示例:

for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
}, 1000);
}

预期输出是 0、1、2、3、4,但实际上输出的是 5、5、5、5、5。因为 setTimeout 函数是一个异步操作,它会在循环结束后再执行。当 setTimeout 函数被调用时,i 的值已经变成了 5,因此它会输出 5,而不是预期的 0、1、2、3 和 4。为了解决这个问题,可以使用闭包或 let 关键字来解决变量作用域的问题。

通过使用闭包来保存变量的值来解决该问题:

for (var i = 0; i < 5; i++) {
(function (j) {
setTimeout(function () {
console.log(j);
}, 1000);
})(i);
}
// 输出 0、1、2、3、4

5、引用类型比较问题:

在 JavaScript 中,引用类型(如数组和对象)的比较可能导致一些奇怪的问题。以下是一个引用类型比较导致的问题示例:

console.log([] == []); // 输出 false
console.log([] === []); // 输出 false

这是因为 JavaScript 中比较引用类型时,比较的是它们在内存中的地址,而不是它们的内容。因此,两个空数组虽然看起来相同,但它们在内存中的地址不同,因此比较结果为 false。

6、变量命名问题:

不恰当的变量命名可能导致一些问题。以下是一个变量命名导致的问题示例:

var NaN = "not a number";
console.log(NaN); // 输出 NaN
console.log(typeof NaN); // 输出 "number"

因为 NaN 是 JavaScript 中一个关键字,表示 Not a Number,不应该被用作变量名。因为变量名和关键字相同,所以 typeof 操作符返回了 "number",而不是预期的 "string"。

7、数据类型转换问题:

JavaScript 中有很多不同的数据类型,类型转换可能导致一些奇怪的问题。以下是一个数据类型转换导致的问题示例:

console.log(1 + "2" + "2"); // 输出 "122"
console.log(1 + +"2" + "2"); // 输出 "32"
console.log(1 + -"1" + "2"); // 输出 "02"
console.log(+"1" + "1" + "2"); // 输出 "112"
console.log("A" - "B" + "2"); // 输出 "NaN2"
console.log("A" - "B" + 2); // 输出 NaN

这些奇怪的输出都是因为类型转换造成的,例如在第一行中,数字 1 和字符串 "2" 相加,得到字符串 "12",然后再和字符串 "2" 相加,得到字符串 "122"。

8、NaN 的比较问题

NaN 是一种特殊的数值,表示 "Not a Number"。在 JavaScript 中,NaN 与任何值都不相等,包括它自己。以下是一个 NaN 比较导致的问题示例:

console.log(NaN == NaN); // 输出 false
console.log(NaN === NaN); // 输出 false

解决该问题的方法是使用全局函数 isNaN() 来判断一个值是否为 NaN:

console.log(isNaN(NaN)); // 输出 true

9、0.1 + 0.2 不等于 0.3 问题

在 JavaScript 中,使用浮点数进行计算时,可能会出现精度问题。例如,0.1 + 0.2 的结果并不是 0.3。以下是一个精度问题导致的问题示例:

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

解决该问题的方法是将浮点数转换为整数进行计算,最后再将结果除以 10。或者使用 Number.EPSILON 来比较两个浮点数是否相等:

console.log(Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON); // 输出 true

参考:JavaScript 中 0.1+0.2 不等于 0.3 的问题

最新文章

  1. PHP的学习--连接MySQL的三种方式
  2. React Native 开发之 (06) JSX
  3. js计算日期之间的月份差
  4. thinkphp的mvc理解
  5. [办公自动化] 再读《让EXCEL飞》(从excel导入access数据时,union联合查询,数据源中没有包含可见的表格)
  6. Java中常用的内存区域
  7. 为Apache配置虚拟机Virtual Host
  8. hdu 2047
  9. SVN与TortoiseSVN实战:标签与分支
  10. POJ 1833 排列
  11. 男性在下一100层【第三层】——高仿手机银行client接口
  12. MySQL数据转移至MSSQL详解
  13. sk_buff整理笔记(两、操作函数)
  14. 如何清除应用程序承载 WebBrowser 控件时缓存
  15. 开始你的第一个npm脚本工具
  16. LeetCode(110):平衡二叉树
  17. Spring使用笔记(四) 面向切面的Spring
  18. 乾坤合一~Linux设备驱动之终端设备驱动
  19. C#模拟请求,模拟登录,Cookie设置、文件上传等问题汇总
  20. layui利用jQuery设置下拉列表的值

热门文章

  1. LeetCode HOT 100:下一个排列
  2. 使用xshell连接linux虚拟机
  3. [常用工具] Python视频处理库VidGear使用指北
  4. [OpenCV实战]14 使用OpenCV实现单目标跟踪
  5. 04-Sed操作参数
  6. Gvim基础操作(正则表达式)-02
  7. Spring Cloud服务发现组件Eureka
  8. C Primer Plus(4.8)編程練習
  9. Ionic 设置全局变量,三种方法设置图片一种是直接增加,一种是replace,第三种是管道和第二种类似
  10. 设置多个系统---vue-el-admin