Skip to content

数据类型与类型转换

题目1: JavaScript中有哪些基本数据类型?

答案: JavaScript中的基本数据类型包括:undefinednullbooleannumberstringsymbol(ES6引入)和bigint(ES11引入)。

扩展: 除了基本数据类型,JavaScript还有一种复杂数据类型:objectobject包括对象、数组、函数等。基本数据类型存储的是值,而复杂数据类型存储的是引用地址。

题目2: =====的区别是什么?

答案: ==进行的是类型转换的比较,===进行的是严格比较,不会进行类型转换。使用===可以避免隐式类型转换带来的问题,推荐使用。

扩展: ==会在比较前尝试进行类型转换,比如数字与字符串进行比较时会将字符串转换为数字。例如:1 == '1'返回true,而1 === '1'返回false

题目3: 如何检测一个变量的类型?typeofinstanceofObject.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: 什么时候会发生隐式类型转换?如何避免?

答案: 隐式类型转换主要发生在以下情况:

  1. 使用==进行比较
  2. 使用+运算符时,如果有一个操作数是字符串
  3. 逻辑运算符(&&||!
  4. 条件语句中的条件表达式

避免隐式类型转换的方法:

  1. 使用===!==进行比较
  2. 在进行运算前,显式地将变量转换为期望的类型
  3. 使用类型检查函数(如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

处理方法:

  1. 对于金融计算,可以将小数转换为整数进行计算,然后再除以相应的倍数。
  2. 使用专门的库,如decimal.jsbig.js
  3. 使用Number.EPSILON进行近似相等比较。

扩展: Number.EPSILON是JavaScript能够表示的最小精度。对于比较小数是否相等,可以使用如下函数:

javascript
function areEqual(a, b) {
  return Math.abs(a - b) < Number.EPSILON;
}

题目7: 解释一下JavaScript中的装箱和拆箱操作。

答案:

  • 装箱(Boxing):将基本数据类型转换为对应的引用类型的操作。例如,将number类型转换为Number对象。
  • 拆箱(Unboxing):将引用类型转换为对应的基本数据类型的操作。

扩展:

  • 装箱操作通常是隐式的,例如调用基本类型的方法时(如"hello".toUpperCase())。
  • 拆箱操作通常通过valueOf()toString()方法实现。
  • 过度使用装箱和拆箱操作可能会影响性能,特别是在循环中。

题目8: 什么是类型强制转换?请举例说明。

答案: 类型强制转换是指将一种数据类型的值转换为另一种数据类型的值。JavaScript中的强制类型转换主要有以下几种:

  1. 转换为字符串:使用String()函数或者toString()方法
  2. 转换为数字:使用Number()函数、一元加操作符(+)或parseInt()/parseFloat()函数
  3. 转换为布尔值:使用Boolean()函数或者!!操作符

扩展:

javascript
String(123); // "123"
(123).toString(); // "123"

Number("123"); // 123
+"123"; // 123
parseInt("123"); // 123

Boolean(1); // true
!!1; // true

题目9: Object.is()===有什么区别?

答案: Object.is()===大多数情况下的行为是相同的,但有两个特殊情况:

  1. Object.is(NaN, NaN)返回true,而NaN === NaN返回false
  2. Object.is(+0, -0)返回false,而+0 === -0返回true

扩展: Object.is()是ES6引入的新方法,用于解决===在处理NaN和正负零时的一些特殊情况。在大多数情况下,使用===就足够了,但如果需要区分+0-0,或者需要将NaN视为相等,那么Object.is()会更合适。

题目10: 解释一下JavaScript中的真值(truthy)和假值(falsy)。

答案: 在JavaScript中,当一个值在布尔上下文中被评估时,它会被强制转换为布尔值truefalse

假值(Falsy)包括:

  • false
  • 0
  • ''(空字符串)
  • null
  • undefined
  • NaN

除了这些假值,其他所有值都是真值(Truthy)。

扩展:

  • 空数组([])和空对象({})都是真值,这可能会导致一些意外情况。
  • 在条件语句中,JavaScript会自动进行布尔转换,例如:
    javascript
    if ([]) {
      console.log("This will be executed!");
    }
  • 使用双重否定(!!)可以将任何值显式转换为其对应的布尔值:
    javascript
    !![] // true
    !!0  // false