第一篇 JS数据类型之概念篇

目录
文章目录隐藏
  1. 1. JS 原始数据类型有哪些?引用数据类型有哪些?
  2. 2. 说出下面运行的结果,解释原因。
  3. 3. null 是对象吗?为什么?
  4. 4. ‘1’.toString()为什么可以调用?
  5. 5. 0.1+0.2 为什么不等于 0.3?
  6. 6. 如何理解 BigInt?
  7. 更多相关文章推荐:

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"

值得警惕的点:

      1. BigInt 不支持一元加号运算符, 这可能是某些程序可能依赖于 + 始终生成 Number 的不变量,或者抛出异常。另外,更改 + 的行为也会破坏 asm.js 代码。
      2. 因为隐式类型转换可能丢失信息,所以不允许在 bigint 和 Number 之间进行混合操作。当混合使用大整数和浮点数时,结果值可能无法由 BigInt 或 Number 精确表示。
        10 + 10n;    // → TypeError
      3. 不能将 BigInt 传递给 Web api 和内置的 JS 函数,这些函数需要一个 Number 类型的数字。尝试这样做会报 TypeError 错误。
        Math.max(2n, 4n, 6n);    // → TypeError
        
      4. 当 Boolean 类型与 BigInt 类型相遇时,BigInt 的处理方式与 Number 类似,换句话说,只要不是 0n,BigInt 就被视为 truthy 的值。
        if(0n){//条件判断为 false
        
        }
        if(3n){//条件为 true
        
        }
        
      5. 元素都为 BigInt 的数组可以进行 sort。
      6. BigInt 可以正常地进行位运算,如|、&、<<、>>和^

浏览器兼容性

caniuse 的结果:

浏览器兼容性

其实现在的兼容性并不怎么好,只有 chrome67、firefox、Opera 这些主流实现,要正式成为规范,其实还有很长的路要走。

我们期待 BigInt 的光明前途!

更多相关文章推荐:

(建议收藏)原生 JS 知识系统整理

 

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系maynote@foxmail.com处理
码云笔记 » 第一篇 JS数据类型之概念篇

发表回复