[TOC] # 面试真题 ## 1\. 说说`js`中有哪些数据类型 ## 2\. js有哪些原始/值/基本,数据类型 ## 3\. 如何判断空对象 ## 4\. BigInt解决了什么问题 ## 5\. 基本类型和引用类型的区别 ## 6\. null和undefined有什么区别 ## 7\. 如何准确区分所有数据类型 # 帮助理解 `JavaScript` 是一种弱类型说动态语言。这意味着你不用提前声明变量的类型,在程序运行过程中,类型会被自动确定。这也意味着你可以使用同一个变量保存不同类型的数据,因此`JavaScript`的数据类型相对而言比较少。 ~~~javascript m = 7; console.log(typeof m) // number m = "最编程"; console.log(typeof m) // string m = true; console.log(typeof m) // boolean ~~~ 从运行结果可以看出来`m`变量的数据类型是由它的值来决定的 ## 基本数据类型 ES5中有5种简单数据类型(也称为基本数据类型):`undefined`、`Null`、`Boolean`、`Number`、`String` ES6中新增了:`symbol` ES10中新增了:`biginit` 所以最新的基本数据类型现在一共是<span class="vip">7</span>个 ### undefined `undefined`类型只有一个值,即特殊的`undefined`也就是它自身。在使用`var`声明变量但未对其加以初始化时,这个变量的值就是`undefined` ~~~javascript var m; console.log(m === undefined) // true ~~~ ### Null `null`类型是第二个只有一个值的数据类型,这个特殊的值是`null`也就是它自身。从逻辑角度来看,`null` 值表示一个空对象指针,而这也正是使用`typeof`操作符检测`null`值时会返回`object`的原因。 ~~~javascript var m = null; console.log(typeof m) // object ~~~ ### Boolean 布尔类型,该类型有两个值:`true`和`false`。布尔值 `true` 代表“真”,`false` 代表“假”。 下面6种值转化为布尔值时为`false`,其他转化都为`true` 1. `undefined`(未定义,找不到值时出现) ~~~javascript let m = undefined; if (m) console.log('最编程') // 不会执行,因为m的值为false ~~~ 2. `null`(代表空值) ~~~javascript let m = null; if (m) console.log('最编程') // 不会执行,因为m的值为false ~~~ 3. `false`(布尔值的`false`,字符串"`false`"布尔值为`true`) ~~~javascript let m = 'false'; if (m) console.log('最编程') // 最编程 ~~~ 4. `0`(数字0,字符串"0"布尔值为`true`) ~~~javascript let m = 0; if (m) console.log('最编程') // 不会执行,因为m的值为false // 字符串"0"布尔值为 true let m = '0'; if (m) console.log('最编程') // 最编程 ~~~ 5. `NaN`(无法计算结果时出现,表示"非数值";但是`typeof NaN==="number"`) ~~~javascript let m = NaN; if (m) console.log('最编程') // 不会执行,因为m的值为false // NaN数据类型为number console.log(typeof NaN) // number ~~~ 6. `""`(双引号)或`''`(单引号) (空字符串,中间有空格时也是`true`) ~~~javascript let m = ''; if (m) console.log('最编程') // 不会执行,因为m的值为false // 空字符串,中间有空格时也是true let m = ' '; if (m) console.log('最编程') // 最编程 ~~~ ### Number `JavaScript`中只有一种数字类型:基于 IEEE 754 格式来表示整数和浮点数值,所有数字在`JavaScript`中均用浮点数值表示,无法精确表示的非常大的整数将自动四舍五入。确切地说,`JS`中的`Number`类型只能安全地表示`2^53 = 9007199254740992之间的整数`(2的53次方- 1,9007199254740992-1,16位),任何超出此范围的整数值都可能失去精度,所以在进行数字运算的时候要特别注意精度缺失问题。 ~~~javascript console.log(9999999999999999); // 10000000000000000 ~~~ 该整数大于`JS Number` 类型所能表示的最大整数,因此,它被四舍五入了。意外四舍五入会损害程序的可靠性和安全性 ### String 字符串类型用于表示文本数据,字符串可以是单引号也可以是双引号,它们是完全相同的 ~~~javascript var m1 = '最编程' var m2 = "创未来" ~~~ ### symbol `ES6` 引入了一种新的原始(基本)数据类型 `Symbol` ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名 ~~~javascript let sy = Symbol("key1"); // 写法1 let syObject = {}; syObject[sy] = "mm"; console.log(syObject); // {Symbol(key1): "mm"} // 写法2 let syObject = { [sy]: "mm" }; console.log(syObject); // {Symbol(key1): "mm"} ~~~ ### bigint `BigInt`类型是 `JavaScript`中的一个基础的数值类型,可以用任意精度表示整数。使用 `BigInt`,您可以安全地存储和操作大整数,甚至可以超过数字的安全整数限制。BigInt数据类型的目的是比Number数据类型支持的范围更大的整数值,使用`BigInt`,整数溢出将不再是问题。此外,可以安全地使用更加准确时间戳,大整数`ID`等,而无需使用变通方法。`BigInt` 是通过在整数末尾附加`n` 或调用构造函数来创建的。 ~~~javascript // 创建BigInt的方法,第一种:只需在整数的末尾追加n即可 let m1 = 7n; // 第二种:BigInt()构造函数 let m2 = BigInt(7); // 这俩货是相等的 console.log(m1 === m2); // true ~~~ 使用 `typeof` 测试时, `BigInt` 返回 `"bigint"` : ~~~javascript let m1 = 7n; console.log(typeof m1) // bigint let m2 = BigInt(7); console.log(typeof m2) // bigint ~~~ 它在某些方面类似于`Number` ,但是也有几个关键的不同点:不能用于 `Math `对象中的方法: ~~~javascript let m = 7n console.log(Math.round(m)) // Cannot convert a BigInt value to a number(无法将BigInt值转换为数字) ~~~ 不能和任何 `Number `实例混合运算,两者必须转换成同一种类型 ~~~javascript let m = 7n let n = 7 console.log(m + n) // Cannot mix BigInt and other types, use explicit conversions(无法混合BigInt和其他类型,请使用显式转换 ~~~ 在两种类型来回转换时要小心,因为 `BigInt `变量在转换成 `Number `变量时可能会丢失精度。 **bigint和number对比:** ~~~javascript // bigint数据类型 console.log(9007199254740995n) // 9007199254740995n // number数据类型(把后面的n去掉) console.log(9007199254740995) // 9007199254740996 ~~~ `BigInt` 和 `Number`不是严格相等的,但是宽松相等的 ~~~javascript let m = 7n let n = 7 console.log(m === n) // false console.log(m == n) // true ~~~ `Number `和 `BigInt `可以进行比较 ~~~javascript console.log(1n < 2) // true console.log(2n > 1) // true console.log(2 > 2) // false console.log( 2n > 2) // false console.log(2n >= 2) // true ~~~ 两者也可以混在一个数组内并排序 ~~~javascript const arr = [3n, 4, 2, 1n, 0, -1n]; console.log(arr.sort()); // (6)[-1n, 0, 1n, 2, 3n, 4] ~~~ ## 引用数据类型 ### Object `Object`类型,我们也称为一个对象。是`JavaScript`中的引用数据类型。它是一种复合值,它将很多值聚合到一起,可以通过名字访问这些值 ~~~javascript // 创建对象 let obj = {} // 添加属性 obj.age = 20 // 添加方法 obj.fn = function() { alert(obj.age) } // 调用对象内的方法 obj.fn() ~~~ 对象除了可以创建自有属性,还可以通过从一个名为原型的对象那里继承属性。 除了`String`、`Number`、`Boolean`、`null`和`undefined`之外,`JS`中的值都是对象 在此类型下面还有子类型:`Array`、`Function`、`Date`、`RegExp` # 真题解答 ## 1\. 说一说`JS`中有哪些数据类型? 首先,我来介绍一下基本数据类型,在`ES5`中有`5`种基本数据类型,分别是:`undefined`、`Null`、`Boolean`、`Number`、`String`。在`ES6`中新增了:`symbol`表示独一无二的值,通过 `Symbol`函数调用生成,由于生成的`symbol`值为原始类型,所以 `Symbol` 函数不能使用`new`调用。在`ES10`中新增了:`biginit`可以用任意精度表示整数。所以最新的基本数据类型现在一共是<span class="vip">`7`</span>个。 其次,就是`object`,它是`JavaScript`中的引用数据类型。是一种复合值,它将很多值聚合到一起,可以通过名字访问这些值,此类型下面还有子类型:`Array`、`Function`、`Date`、`RegExp`。 ## 2\. js有哪些原始/值/基本,数据类型 在`ES5`中有`5`种基本数据类型,分别是:`undefined`、`Null`、`Boolean`、`Number`、`String`。在`ES6`中新增了:`symbol`表示独一无二的值,通过 `Symbol` 函数调用生成,由于生成的 `symbol` 值为原始类型,所以 `Symbol` 函数不能使用 `new`调用。在`ES10`中新增了:`biginit`可以用任意精度表示整数。所以最新的基本数据类型现在一共是<span class="vip">`7`</span>个。 ## 3\. 如果判断空对象 第一种方法:使用`JSON.stringify()`转为对象字符串判断是否全等于`"{}"` ~~~javascript let obj = {}; console.log(JSON.stringify(obj) === '{}') // true ~~~ 第二种方法:因为`for in`只能枚举对象自身的属性,不能枚举原型属性,因此可以用来判断是否为空对象 ~~~javascript function isEmptyObject(obj) { for (var key in obj) { return false; } return true; } console.log((isEmptyObject({}))) // true ~~~ 第三种方法:`Object.keys`也是只能获取自身属性,不能获取原型属性 ~~~javascript function isEmptyObject(obj) { return Object.keys(obj).length === 0; } console.log(isEmptyObject({})) // true ~~~ ## 4\. `BigInt` 解决了什么问题? `JavaScript`中能表示的最⼤安全数字,转换成`10`进制是`9007199254740991`,即在这个数范围内不会出现精度丢失(⼩数除外)。但是⼀旦超过这个范围,`js`就会出现计算不准确的情况,这在⼤数计算的时候不得不依靠⼀些第三⽅库进⾏解决,因此官⽅提出了`BigInt`来解决此问题。 ## 5\. 基本类型和引用的区别 稍后更新... ## 6\. null和undefined有什么区别? 稍后更新... ## 7\. 如何准确区分所有数据类型? 稍后更新...