第一篇 JS数据类型之概念篇
1. JS 原始数据类型有哪些?引用数据类型有哪些?
在 JS 中,存在着 7 种原始值,分别是:
- boolean
- null
- undefined
- number
- string
- symbol
- bigint
引用数据类型: 对象 Object(包含普通对象-Object,数组对象-Array,正则对象-RegExp,日期对象-Date,数学函数-Math,函数对象-Function)
2. 说出下面运行的结果,解释原因。
function test(person) { person.age = 26 person = { name: 'mybj', age: 18 } return person } const p1 = { name: 'gwei', age: 19 } const p2 = test(p1) console.log(p1) // -> ? console.log(p2) // -> ?
运行结果:
p1:{name: “gwei”, age: 26} p2:{name: “mybj”, age: 18}
原因: 在函数传参的时候传递的是对象在堆中的内存地址值,test 函数中的实参 person 是 p1 对象的内存地址,通过调用 person.age = 26 确实改变了 p1 的值,但随后 person 变成了另一块内存空间的地址,并且在最后将这另外一份内存空间的地址返回,赋给了 p2。
3. null 是对象吗?为什么?
结论:null 不是对象。
解释:虽然 typeof null 会输出 object,但是这只是 JS 存在的一个悠久 Bug。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象然而 null 表示为全零,所以将它错误的判断为 object。
4. ‘1’.toString()为什么可以调用?
其实在这个语句运行的过程中做了这样几件事情:
var s = new Object('1'); s.toString(); s = null;
第一步:创建 Object 类实例。注意为什么不是 String?由于 Symbol 和 BigInt 的出现,对它们调用 new 都会报错,目前 ES6 规范也不建议用 new 来创建基本类型的包装类。
第二步:调用实例方法。
第三步:执行完方法立即销毁这个实例。
整个过程体现了基本包装类型的性质,而基本包装类型恰恰属于基本数据类型,包括 Boolean,Number 和 String。
参考:《JavaScript 高级程序设计(第三版)》P118
5. 0.1+0.2 为什么不等于 0.3?
0.1 和 0.2 在转换成二进制后会无限循环,由于标准位数的限制后面多余的位数会被截掉,此时就已经出现了精度的损失,相加后因浮点数小数位的限制而截断的二进制数字在转换为十进制就会变成 0.30000000000000004。
6. 如何理解 BigInt?
什么是 BigInt?
BigInt 是一种新的数据类型,用于当整数值大于 Number 数据类型支持的范围时。这种数据类型允许我们安全地对大整数执行算术操作,表示高分辨率的时间戳,使用大整数 id,等等,而不需要使用库。
为什么需要 BigInt?
在 JS 中,所有的数字都以双精度 64 位浮点格式表示,那这会带来什么问题呢?
这导致 JS 中的 Number 无法精确表示非常大的整数,它会将非常大的整数四舍五入,确切地说,JS 中的 Number 类型只能安全地表示-9007199254740991(-(2^53-1))和 9007199254740991((2^53-1)),任何超出此范围的整数值都可能失去精度。
console.log(999999999999999); //=>10000000000000000
同时也会有一定的安全性问题:
9007199254740992 === 9007199254740993; // → true 居然是 true!
如何创建并使用 BigInt?
要创建 BigInt,只需要在数字末尾追加 n 即可。
console.log( 9007199254740995n ); // → 9007199254740995n console.log( 9007199254740995 ); // → 9007199254740996
另一种创建 BigInt 的方法是用 BigInt()构造函数
BigInt("9007199254740995"); // → 9007199254740995n
简单使用如下:
10n + 20n; // → 30n 10n - 20n; // → -10n +10n; // → TypeError: Cannot convert a BigInt value to a number -10n; // → -10n 10n * 20n; // → 200n 20n / 10n; // → 2n 23n % 10n; // → 3n 10n ** 3n; // → 1000n const x = 10n; ++x; // → 11n --x; // → 9n console.log(typeof x); //"bigint"
值得警惕的点:
-
-
- BigInt 不支持一元加号运算符, 这可能是某些程序可能依赖于 + 始终生成 Number 的不变量,或者抛出异常。另外,更改 + 的行为也会破坏 asm.js 代码。
- 因为隐式类型转换可能丢失信息,所以不允许在 bigint 和 Number 之间进行混合操作。当混合使用大整数和浮点数时,结果值可能无法由 BigInt 或 Number 精确表示。
10 + 10n; // → TypeError
- 不能将 BigInt 传递给 Web api 和内置的 JS 函数,这些函数需要一个 Number 类型的数字。尝试这样做会报 TypeError 错误。
Math.max(2n, 4n, 6n); // → TypeError
- 当 Boolean 类型与 BigInt 类型相遇时,BigInt 的处理方式与 Number 类似,换句话说,只要不是 0n,BigInt 就被视为 truthy 的值。
if(0n){//条件判断为 false } if(3n){//条件为 true }
- 元素都为 BigInt 的数组可以进行 sort。
- BigInt 可以正常地进行位运算,如|、&、<<、>>和^
-
浏览器兼容性
caniuse 的结果:
其实现在的兼容性并不怎么好,只有 chrome67、firefox、Opera 这些主流实现,要正式成为规范,其实还有很长的路要走。
我们期待 BigInt 的光明前途!
更多相关文章推荐:
![](https://media.mybj123.com/wp-content/uploads/2024/02/1706962282-d2a91681b352c3a.png)