面试题
JS 中有哪些数据类型,它们的区别?
为什么有的编程规范要求用 void 0 代替 undefined?
0.1 + 0.2 === 0.3 ?
字符串有长度限制吗?有的话是多少?
"𠯿".length?
大家在看具体内容之前可以停留几分钟先仔细看一下各大厂商对这一块内容的面试题难度是如何的,并尝试自己回答一下,看看自己是否能回答上来,然后带着自己的疑问或者不懂的知识点去看下面的内容,相信一定会有事半功倍的效果。
分类
这一节主要是介绍JavaScript的数据类型,根据最新的ECMAScript标准定义了8种数据类型:
-
七种基本数据类型
- 布尔值(Boolean)
- 空值(Null)
- 未定义值(Undefined)
- 数字(Number)
- 任意精度的整数(BigInt)
- 字符串(String)
- 符号(Symbol)
-
以及引用类型
- 对象(Object)
- 数组(Array)
- 函数(Function)
- 日期(Date)
- 正则(Regexp)
基本数据类型
布尔值
布尔类型表示一个逻辑实体,可以有两个值:true 和 false
空值
空值 null 是一个字面量,它不像 undefined 是一个全局对象的一个属性。null 是表示缺少的标识,指示变量未指向任何对象。
ini
a;
> VM57:1 Uncaught ReferenceError: a is not defined
at <anonymous>:1:1
let a = null;
a;
> null
未定义值
Undefined类型只有一个值,称为undefined,任何没有赋值的变量的值都是undefined。同时 undefined 是全局对象的一个属性,并不是保留字。也就是说,它是全局作用域的一个变量,并且在ES5之前,全局undefined的值是可以进行修改的,尽管在ES5及之后,全局undefined的值不再允许修改,但是如果在局部作用域内定义一个相同的undefined变量,那么其依然可以覆盖掉全局undefined。
javascript
var a;
console.log(a);
> undefined
console.log(window.undefined === undefined)
> true
// undefined 属性描述
Object.getOwnPropertyDescriptor(window, 'undefined')
> configurable: false
> enumerable: false
> value: undefined
> writable: false
> __proto__: Object
// undefined 局部变量
(function () {
var undefined = 1
console.log(undefined) // 结果是?
})()
> 1
数字
所有的数字都是以双精度64位二进制格式 IEEE 754-2019 形式储存,其表示方法有两种形式,第一种是整数,第二种为浮点数,除此之外还有三种特殊的数值:NaN、 Infinity、-Infinity。
整数
- 十进制:JavaScript 默认进制数
- 八进制数:第一位必须是 0,然后是 0-7 的数字组成
- 十六进制:前面两位必须是 0x,然后是 0-9 及 A-F(字母不区分大小写)
浮点数
浮点数中必须包含一个小数点,并且小数点后面必须至少有一位数字,其有两种表现形式,第一种就是用普通的小数表示法、第二种就是使用科学计数法。所有的浮点数都是采用的IEEE 754的双精度标准进行存储,由于存储长度有限,因此会存在精度丢失的问题。对于像0.1这样的数字用二进制表示你就会发现无法整除,最后算下来会是 0.000110011......由于存储空间有限,最后计算机会舍弃后面的数字,所以我们最后就只能得到一个近似值,因此会发现有一些数字计算与预期不符:例如:0.1 + 0.2 = 0.30000000000000004。
ini
0.1 + 0.2 === 0.3
> false
NaN
NaN(not a number)是一个特殊种类的数值,当算术运算的结果不表示数值时,通常会遇到它。它也是 JavaScript 中唯一不等于自身的值。
arduino
5 - 'x'
> NaN
Infinity
Infinity也是一个特殊种类的数值,它比任何有限数字都大,其分别有 Infinity(正无穷大) 和 - Infinity(负无穷大)。需要注意的是 Infinity 加任何正数都等于Infinity,-Infinity 减任何正数都等于 -Infinity。
arduino
console.log(Infinity + 100 === Infinity)
> true
console.log(-Infinity - 100 === -Infinity)
> true
BigInt
BigInt是ES11引入的新的基本数据类型。它可以表示任意大小的整数。使用 BigInt,你可以安全地存储和操作巨大的整数,甚至超过 Number 的安全整数限制(Number支持的最大安全整数是2^53 - 1)。BigInt 是通过将 n
附加到整数末尾或调用 BigInt()
函数来创建的。
ini
const theBiggestInt = 9007199254740991n;
String
String 类型表示文本数据并编码为 UTF-16 代码单位的 16 位无符号整数值序列,字符串的长度是其中的 UTF-16 代码单元的数量,最大长度为2^53 - 1(Number支持的最大安全整数是2^53 - 1,因此序列最大长度为2^53 - 1)。
在 UTF-16 编码中,每个码元都是 16 位长。这意味着最多有 2^16 个或 65536 个可能的字符可表示为单个 UTF-16 码元。然而,整个 Unicode 字符集(Unicode 的编码区间是 0x0000~0x10FFFF)比 65536 大得多,因此每个 Unicode 字符由一个或者两个 UTF-16 码元组成。
arduino
"𠯿".length // 由两个码元组成
> 2
"六".length // 由一个码元组成
> 1
Symbol
符号(Symbols)是 ECMAScript 第 6 版新定义的,它表示一个唯一的常量。该类型的性质在于这个类型的值可以用来创建匿名的对象属性。该数据类型通常被用作一个对象属性的键值,当这个属性是用于类或对象类型的内部使用的时候。
ini
let privateVarible = Symbol();
this[privateVarible] = 2;
引用数据类型
Object
Object是 JavaScript 的一种 数据类型 。它用于存储各种键值集合和更复杂的实体。Objects 可以通过 Object()
构造函数或者使用 对象字面量 的方式创建。简而言之,Object是JS里唯一一种复杂的数据类型,是无序的键值对(key-value)的集合。
ini
let o = new Object();
let a = {};
答案
如果大家有仔细看过上面的内容的话,我相信文章开头的面试题,大家都能够游刃有余的回答出来,那么在看具体的答案之前,先自己组织语言再回答一下吧。
问1:JS中有哪些数据类型,它们的区别?
javascript
答:总共有8种数据类型,其中基本数据类型有7种,分别是Boolean、Null、Undefined、Number、BigInt、
String、Symbol,还有一种引用类型。Boolean是布尔类型,只有true、false两种值;Null是表示缺少的标识,指
示变量未指向任何对象;Undefined类型的值是undefined,代表变量未赋值;Number是数字类型,使用 64 位 IEEE
754表示;BigInt是ES11引入的新的基本数据类型,它可以表示任意大小的整数,主要是为了解决Number无法安全地
存储和操作巨大整数的问题;String 类型表示文本数据并编码为 UTF-16 代码单位的 16 位无符号整数值序列;符号
(Symbols)是 ECMAScript 第 6 版新定义的,它表示一个唯一的常量。
问2:为什么有的编程规范要求用 void 0代替undefined?
javascript
答:undefined 是全局对象的一个属性,并不是保留字。也就是说,它是全局作用域的一个变量,并且在ES5之前,全
局undefined的值是可以进行修改的,尽管在ES5之后,全局undefined的值不再允许修改,但是如果在局部作用域内定
义一个相同的undefined变量,那么其依然可以覆盖掉全局undefined,而 void 0 总是返回原始值 undefined,无
论全局属性 undefined 是否被改写,它都能确保其值是 undefined。
问3:0.1+0.2===0.3?
ini
答:0.1 + 0.2 !== 0.3
因为在JavaScript中,所有的数值都是采用的IEEE 754的双精度标准进行存储,其尾数有长度的限制(小于52位),
因此会存在精度丢失的问题。对于像0.1这样的数字用二进制表示你就会发现无法整除,最后算下来会是
0.000110011......由于存储空间有限,最后计算机会舍弃后面的数字,所以我们最后就只能得到一个近似值,对于 0.2
存在同样的问题,因此最终会发现 0.1+0.2 = 0.30000000000000004,而不是预期的 0.3。
问4:字符串有长度限制吗?有的话是多少?
python
答:字符串有长度的限制,规定上其最大长度为 2^53 - 1(因为数值的最大安全整数是 2^53 - 1,那么str.length
能得出的最大值即为 2^53 - 1),但现实中没有浏览器允许这么长的字符串。
问5:"𠯿".length?
vbnet
答:"𠯿".length = 2
String 类型表示文本数据并编码为 UTF-16 代码单位的 16 位无符号整数值序列,字符串的长度是其中的 UTF-16
代码单元的数量。在 UTF-16 编码中,每个码元都是 16 位长。这意味着最多有 2^16 个或 65536 个可能的字符可
表示为单个 UTF-16 码元。然而,整个 Unicode 字符集(Unicode 的编码区间是 0x0000~0x10FFFF)比 65536
大得多,因此每个 Unicode 字符由一个或者两个 UTF-16 码元组成,而 𠯿 恰好由两个 UTF-16 码元组成(0xD842
0xDFFF),故长度为 2.
参考资料:
[1] 语法和数据类型:developer.mozilla.org/zh-CN/docs/...
[2] 262.ecma-international.org/#sec-ecmasc...