数据类型与类型转换
题目1: JavaScript中有哪些基本数据类型?
答案: JavaScript中的基本数据类型包括:undefined、null、boolean、number、string、symbol(ES6引入)和bigint(ES11引入)。
扩展: 除了基本数据类型,JavaScript还有一种复杂数据类型:object。object包括对象、数组、函数等。基本数据类型存储的是值,而复杂数据类型存储的是引用地址。
题目2: ==和===的区别是什么?
答案: ==进行的是类型转换的比较,===进行的是严格比较,不会进行类型转换。使用===可以避免隐式类型转换带来的问题,推荐使用。
扩展: ==会在比较前尝试进行类型转换,比如数字与字符串进行比较时会将字符串转换为数字。例如:1 == '1'返回true,而1 === '1'返回false。
题目3: 如何检测一个变量的类型?typeof、instanceof和Object.prototype.toString.call()的区别?
答案:
typeof操作符可以检测基本数据类型(除了null)和函数。instanceof用于检测对象是否为某个构造函数的实例。Object.prototype.toString.call()可以精确地检测任何类型。
扩展:
typeof null返回"object",这是JavaScript的一个历史遗留bug。instanceof不能跨框架(iframe)使用,因为每个框架都有自己的执行环境。Object.prototype.toString.call()返回形如"[object Type]"的字符串,其中Type是对象的实际类型。
题目4: 什么时候会发生隐式类型转换?如何避免?
答案: 隐式类型转换主要发生在以下情况:
- 使用
==进行比较 - 使用
+运算符时,如果有一个操作数是字符串 - 逻辑运算符(
&&、||、!) - 条件语句中的条件表达式
避免隐式类型转换的方法:
- 使用
===和!==进行比较 - 在进行运算前,显式地将变量转换为期望的类型
- 使用类型检查函数(如
typeof)来确保类型正确
扩展: 隐式类型转换可能导致意外的结果,例如:[] + {}返回"[object Object]",而{} + []返回0。这是因为JavaScript引擎对这两种表达式的解析方式不同。
题目5: NaN是什么?如何检测一个值是否为NaN?
答案: NaN表示"Not a Number"(不是一个数字),它是一个特殊的数值,用于表示某个值不是合法的数字。检测一个值是否为NaN的最可靠方法是使用Number.isNaN()函数。
扩展:
NaN不等于任何值,包括它自己。因此,NaN === NaN返回false。typeof NaN返回"number",这可能会让人感到困惑。- 早期的
isNaN()函数存在问题,它会将非数字值(如字符串)也判断为NaN。ES6引入的Number.isNaN()修复了这个问题。
题目6: JavaScript中的数字精度问题是如何产生的?如何处理?
答案: JavaScript使用IEEE 754标准的双精度浮点数来表示数字,这会导致某些小数无法精确表示,比如0.1 + 0.2 !== 0.3。
处理方法:
- 对于金融计算,可以将小数转换为整数进行计算,然后再除以相应的倍数。
- 使用专门的库,如
decimal.js或big.js。 - 使用
Number.EPSILON进行近似相等比较。
扩展: Number.EPSILON是JavaScript能够表示的最小精度。对于比较小数是否相等,可以使用如下函数:
function areEqual(a, b) {
return Math.abs(a - b) < Number.EPSILON;
}题目7: 解释一下JavaScript中的装箱和拆箱操作。
答案:
- 装箱(Boxing):将基本数据类型转换为对应的引用类型的操作。例如,将
number类型转换为Number对象。 - 拆箱(Unboxing):将引用类型转换为对应的基本数据类型的操作。
扩展:
- 装箱操作通常是隐式的,例如调用基本类型的方法时(如
"hello".toUpperCase())。 - 拆箱操作通常通过
valueOf()或toString()方法实现。 - 过度使用装箱和拆箱操作可能会影响性能,特别是在循环中。
题目8: 什么是类型强制转换?请举例说明。
答案: 类型强制转换是指将一种数据类型的值转换为另一种数据类型的值。JavaScript中的强制类型转换主要有以下几种:
- 转换为字符串:使用
String()函数或者toString()方法 - 转换为数字:使用
Number()函数、一元加操作符(+)或parseInt()/parseFloat()函数 - 转换为布尔值:使用
Boolean()函数或者!!操作符
扩展:
String(123); // "123"
(123).toString(); // "123"
Number("123"); // 123
+"123"; // 123
parseInt("123"); // 123
Boolean(1); // true
!!1; // true题目9: Object.is()与===有什么区别?
答案: Object.is()和===大多数情况下的行为是相同的,但有两个特殊情况:
Object.is(NaN, NaN)返回true,而NaN === NaN返回falseObject.is(+0, -0)返回false,而+0 === -0返回true
扩展: Object.is()是ES6引入的新方法,用于解决===在处理NaN和正负零时的一些特殊情况。在大多数情况下,使用===就足够了,但如果需要区分+0和-0,或者需要将NaN视为相等,那么Object.is()会更合适。
题目10: 解释一下JavaScript中的真值(truthy)和假值(falsy)。
答案: 在JavaScript中,当一个值在布尔上下文中被评估时,它会被强制转换为布尔值true或false。
假值(Falsy)包括:
false0''(空字符串)nullundefinedNaN
除了这些假值,其他所有值都是真值(Truthy)。
扩展:
- 空数组(
[])和空对象({})都是真值,这可能会导致一些意外情况。 - 在条件语句中,JavaScript会自动进行布尔转换,例如:javascript
if ([]) { console.log("This will be executed!"); } - 使用双重否定(
!!)可以将任何值显式转换为其对应的布尔值:javascript!![] // true !!0 // false