js数据类型分类及存储区别

1. js数据类型分类

在这里插入图片描述

js一共有8种数据类型,7种基本数据类型和1种引用数据类型。

7种基本数据类型UndefinedNullBooleanNumberStringSymboles6新增,表示独一无二的值)和BigIntes10新增)。

  • Symbol 代表独一无二的值,最大的用法是用来定义对象的唯一属性名
  • BigInt 可以表示任意大小的整数。
    需要注意的是, JS中 的数字类型都是浮点类型的,没有整型。

1种引用数据类型Object(Object本质上是由一组无序的名值对组成的,包含普通对象-Object,数组对象-Array,正则对象-RegExp,日期对象-Date,数学函数-Math,函数对象-Function)。

1.1 什么是Symbol类型

ES6 之前的对象属性名都是字符串,这容易造成属性名的冲突
比如说你引入一个同事写的 js 代码,你往他 js 代码里面一个很复杂的对象里面添加新的属性方法,如果是用属性名还是使用字符串的方式,你加的方法就有可能和你同事加的方法重名了。

const str1 = Symbol('name');
const str2 = Symbol('name');
console.log(str1);  //Symbol(name)
console.log(str2);  //Symbol(name)
console.log(str1 === str2); //false

即使是传入相同的参数,生成的Symbol值也是不相等的,因为Symbol本来就是独一无二的意思。

const obj={};
obj[Symbol('name')]='张三';
obj[Symbol('name')]='李四';
console.log(obj);  //{Symbol(name): '张三', Symbol(name): '李四'}

ES6 引入 Symbol 类型让对象的属性名可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。

1.2 什么是BigInt类型

  • 什么是BigInt?
    BigInt是一种新的数据类型,用于当整数值大于Number数据类型支持的范围时。BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示
    这种数据类型允许我们安全地对大整数执行算术操作,表示高分辨率的时间戳,使用大整数id,等等,而不需要使用库。
  • 为什么需要BigInt?
    JS中,所有的数字都以双精度64位浮点格式表示,那这会带来什么问题呢?
    这导致JS中的Number无法精确表示非常大的整数,它会将非常大的整数四舍五入,确切地说,JS中的Number类型只能安全地表示(-2^53-1) 和 (2 ^53-1),任何超出此范围的整数值都可能失去精度。二是大于或等于2的1024次方的数值,JavaScript 无法表示,会返回Infinity
console.log(999999999999999);  //=>10000000000000000

同时也会有一定的安全性问题:

9007199254740992 === 9007199254740993;    // → true 居然是true!
  • 如何创建并使用BigInt
    1.要创建BigInt,只需要在数字末尾追加n即可。
console.log( 9007199254740995n );    // → 9007199254740995n	
console.log( 9007199254740995 );     // → 9007199254740996

2.另一种创建BigInt的方法是用BigInt()构造函数

BigInt("9007199254740995");    // → 9007199254740995n

简单使用如下:

10n + 20n;    // → 30n	
10n - 20n;    // → -10n	
+10n;         // → TypeError: Cannot convert a BigInt value to a number	BigInt不支持一元加号运算符
-10n;         // → -10n	
10n * 20n;    // → 200n	
20n / 10n;    // → 2n	
23n % 10n;    // → 3n	
10n ** 3n;    // → 1000n	
42n === 42 // false BigInt 与普通整数是两种值,它们之间并不相等

const x = 10n;	
++x;          // → 11n	
--x;          // → 9n
console.log(typeof x);   //"bigint" typeof运算符对于 BigInt 类型的数据返回bigint
  • 值得警惕的点
    BigInt不支持一元加号运算符, 因为会与 asm.js (一种提升js执行效率的解决方案)冲突。
    因为隐式类型转换可能丢失信息,所以不允许bigintNumber 之间进行混合操作。当混合使用大整数和浮点数时,结果值可能无法由BigIntNumber精确表示。
10 + 10n;    // → TypeError

不能BigInt传递给Web api和内置的 JS 函数,这些函数需要一个 Number 类型的数字。

Math.max(2n, 4n, 6n);    // → TypeError

Boolean 类型与 BigInt 类型相遇时,BigInt 的处理方式与Number类似,换句话说,只要不是0nBigInt就被视为truthy的值。

if(0n){//条件判断为false

}
if(3n){//条件为true

}
  • 元素都为BigInt的数组可以进行sort。
  • BigInt可以正常地进行位运算,如|&<<>>^

2. 存储方式差异

基本数据类型保存在里面,可以直接访问它的值;引用数据类型保存在里面,里面保存的是地址,通过栈里面的地址去访问堆里面的值。

赋值时,原始类型的赋值会完整复制变量值,两个对象对应不同的地址;而引用类型的赋值是复制引用地址,两个变量指向堆内存中同一个对象。

基本类型示例

let a = 10;
let b = a; // 赋值操作
b = 20;
console.log(a); // 10值

a的值为一个基本类型,是存储在栈中,将a的值赋给b,虽然两个变量的值相等,但是两个变量保存了两个不同的内存地址,所以b的改变不会引起a的变化。

下图是基本类型赋值过程
在这里插入图片描述
引用类型示例1

var obj1 = {
    
    }
var obj2 = obj1;
obj2.name = "xxx";
console.log(obj1.name); // xxx

obj1是一个引用类型,在赋值操作过程汇总,实际是将堆内存对象在栈内存的引用地址复制了一份给了obj2,实际上他们共同指向了同一个堆内存对象,所以更改obj2会对obj1产生影响。

下图是引用类型赋值过程
在这里插入图片描述
引用类型示例2

function test(person) {
    
    
  person.age = 26
  person = {
    
    
    name: 'hzj',
    age: 18
  }
  return person
}
const p1 = {
    
    
  name: 'fyq',
  age: 19
}
const p2 = test(p1)
console.log(p1) // -> ?
console.log(p2) // -> ?
// 结果:
p1:{
    
    name: “fyq”, age: 26}
p2:{
    
    name: “hzj”, age: 18}

原因: 在函数传参的时候传递的是对象在堆中的内存地址值,test函数中的实参person是p1对象的内存地址,通过调用person.age = 26确实改变了p1的值,但随后person变成了另一块内存空间的地址,并且在最后将这另外一份内存空间的地址返回,赋给了p2。

猜你喜欢

转载自blog.csdn.net/weixin_43288600/article/details/121237064
今日推荐