第一篇 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"

值得警惕的点:

      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的结果:

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

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

我们期待BigInt的光明前途!

更多相关文章推荐:

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

 

未经允许不得转载:码云笔记 » 第一篇 JS数据类型之概念篇
喜欢(2) 打赏

评论抢沙发

评论前必须登录!

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏