JavaScript 中的一些奇怪问题
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 的问题
JavaScript 中的一些奇怪问题的更多相关文章
- JavaScript中的"奇奇怪怪"
filter等方法的隐式转化 var list = [1,,2,,0,5,9];console.log(list[1]); // console: undefinedconsole.log(list[ ...
- JavaScript 中的数据类型
Javascript中的数据类型有以下几种情况: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Function,Date,Ar ...
- JavaScript中的this陷阱的最全收集
JavaScript来自一门健全的语言,所以你可能觉得JavaScript中的this和其他面向对象的语言如java的this一样,是指存储在实例属性中的值.事实并非如此,在JavaScript中,最 ...
- JavaScript中的this陷阱的最全收集 没有之一
当有人问起你JavaScript有什么特点的时候,你可能立马就想到了单线程.事件驱动.面向对象等一堆词语,但是如果真的让你解释一下这些概 念,可能真解释不清楚.有句话这么说:如果你不能向一个6岁小孩解 ...
- JavaScript中的apply和call函数详解(转)
每个JavaScript函数都会有很多附属的(attached)方法,包括toString().call()以及apply().听起来,你是否会感到奇怪,一个函数可能会有属于它自己的方法,但是记住,J ...
- 深入理解Javascript中this, prototype, constructor
在Javascript面向对象编程中经常需要使用到this,prototype和constructor这3个关键字. 1.首先介绍一下this的使用:this表示当前对象;如果在全局中使用this,则 ...
- javascript中的链表结构—从链表中删除元素
1.概念 上一个博文我们讲到链表,其中有一个方法remove()是暂时注释的,这个方法有点复杂,需要添加一个Previous()方法找到要删除的元素的前一个节点,这一个博文我们来分析一下这个remov ...
- 深入理解JavaScript中创建对象模式的演变(原型)
深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...
- JavaScript中Eval()函数的作用
这一周感觉没什么写的,不过在研究dwz源码的时候有一个eval()的方法不是很了解,分享出来一起学习 -->首先来个最简单的理解 eval可以将字符串生成语句执行,和SQL的exec()类似. ...
- 转:JavaScript中的this陷阱的最全收集
在其他地方看到的,觉得解释的狠详细,特此分享 当有人问起你JavaScript有什么特点的时候,你可能立马就想到了单线程.事件驱动.面向对象等一堆词语,但是如果真的让你解释一下这些概念,可能真解释不清 ...
随机推荐
- 最大值减去最小值小于或等于 num 的子数组数量问题
最大值减去最小值小于或等于 num 的子数组数量问题 作者:Grey 原文地址: 博客园:最大值减去最小值小于或等于 num 的子数组数量问题 CSDN:最大值减去最小值小于或等于 num 的子数组数 ...
- 快速学会慢查询SQL排查
转载请注明出处️ 作者:测试蔡坨坨 原文链接:caituotuo.top/c56bd0c5.html 你好,我是测试蔡坨坨. 在往期文章中,我们聊过数据库基础知识,可参考「数据库基础,看完这篇就够了! ...
- Kubernetes单机创建MySQL+Tomcat演示程序:《Kubernetes权威指南》第一章demo报错踩坑
引言 最近做边缘计算项目,因为没有基础,所以首先学习Kubernetes.感觉系统的中文入门资料比较少,只找到<Kubernetes权威指南>(龚正.吴治辉等著,下称<指南>) ...
- ArcObjects SDK开发 024开发的技术和技巧
1.基本技术 开发方面.会使用C#开发语言和Visual Studio开发工具.会使用WinForm或者WPF开发. 理论知识方面.了解GIS的相关概念,例如矢量数据,栅格数据,空间参考.比例尺等概念 ...
- 记一次在CentOS上安装GitLab的流程
1.本次环境说明 系统:Centos7.6 IP地址:http://192.168.3.213: 最低配置要求:2核心CPU和4G内存,这是因为[GitLab]的整体运行包含了多个进程 2.自行安装 ...
- java8新特性学习笔记
目录 1.速度更快 2.Lambda表达式 2.1.匿名内部类的Lambda转换 2.2.java8内置的四大核心函数式接口 2.3.方法引用和构造器 2.3.1.方法引用 2.3.2.构造器引用 2 ...
- [机器学习] t-SNE聚类算法实践指南
转载于比PCA降维更高级--(R/Python)t-SNE聚类算法实践指南-阿里云开发者社区 作者介绍:Saurabh.jaju2 Saurabh是一名数据科学家和软件工程师,熟练分析各种数据集 ...
- react 高效高质量搭建后台系统 系列 —— 请求数据
其他章节请看: react 高效高质量搭建后台系统 系列 请求数据 后续要做登录模块(主页),需要先和后端约定JSON数据格式,将 axios 进行封装,实现本地的数据模拟 mockjs. Tip:s ...
- 一文了解华为FusionInsight MRS HBase的集群隔离方案RSGroup
摘要: RSGroup是集群隔离方案. 本文分享自华为云社区<华为FusionInsight MRS HBase的集群隔离--RSGroup>,作者: MissAverage. 一.HBa ...
- [cocos2d-x]用getContentSize()返回的值用CCLOG打印必须用%f
今天写代码,又遇到了一个bug,开始还以为是我自己哪写错了,没想到竟然在这里出错? 而width和height的类型是float类型,为什么必须用%d打印?接着我查看了一下源码: 如果没理解错的话,C ...