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

简介: js数据类型分类及存储区别

1. js数据类型分类


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


7种基本数据类型:Undefined、Null、Boolean、Number、String、Symbol(es6新增,表示独一无二的值)和BigInt(es10新增)。


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 str1 = Symbol('name');
const str2 = Symbol('name');
console.log(str1);  //Symbol(name)
console.log(str2);  //Symbol(name)
console.log(str1 === str2); //false


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执行效率的解决方案)冲突。

因为隐式类型转换可能丢失信息,所以不允许在bigint和 Number 之间进行混合操作。当混合使用大整数和浮点数时,结果值可能无法由BigInt或Number精确表示。

10 + 10n;    // → TypeError

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


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

当 Boolean 类型与 BigInt 类型相遇时,BigInt 的处理方式与Number类似,换句话说,只要不是0n,BigInt就被视为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。

相关文章
|
14天前
|
设计模式 JavaScript 前端开发
js中new和object.creat区别
【10月更文挑战第29天】`new` 关键字和 `Object.create()` 方法在创建对象的方式、原型链继承、属性初始化以及适用场景等方面都存在差异。在实际开发中,需要根据具体的需求和设计模式来选择合适的方法来创建对象。
|
1月前
|
存储 JavaScript 前端开发
JavaScript 数据类型详解:基本类型与引用类型的区别及其检测方法
JavaScript 数据类型分为基本数据类型和引用数据类型。基本数据类型(如 string、number 等)具有不可变性,按值访问,存储在栈内存中。引用数据类型(如 Object、Array 等)存储在堆内存中,按引用访问,值是可变的。本文深入探讨了这两种数据类型的特性、存储方式、以及检测数据类型的两种常用方法——typeof 和 instanceof,帮助开发者更好地理解 JavaScript 内存模型和类型检测机制。
71 0
JavaScript 数据类型详解:基本类型与引用类型的区别及其检测方法
|
1月前
|
存储 JavaScript 前端开发
js中函数、方法、对象的区别
js中函数、方法、对象的区别
16 2
|
1月前
|
JavaScript 前端开发 开发者
【干货拿走】JavaScript中最全的数据类型判断方法!!!!
【干货拿走】JavaScript中最全的数据类型判断方法!!!!
22 1
|
1月前
|
JavaScript 前端开发
【JavaScript】let,const和var的区别
总的来说,随着ECMAScript 6(ES6)及后续版本的推广,`let`和 `const`因其增强的块级作用域和对变量行为的更严格控制,逐渐成为现代JavaScript编码实践中推荐使用的变量声明方式。而 `var`由于其历史遗留的局限性,正逐渐被边缘化,但在维护老代码或处理特定兼容性需求时仍需了解。
35 3
|
2月前
|
前端开发 JavaScript 开发者
React 和 Vue.js 框架的区别是什么?
React 和 Vue.js 框架的区别是什么?
|
1月前
|
存储 JavaScript 前端开发
JavaScript数据类型全解:编写通用函数,精准判断各种数据类型
JavaScript数据类型全解:编写通用函数,精准判断各种数据类型
18 0
|
1月前
|
缓存 JavaScript 前端开发
Node.js模块化的基本概念和分类及使用方法
Node.js模块化的基本概念和分类及使用方法
32 0
|
2月前
|
JavaScript 前端开发
JavaScript中单引号和双引号的效果的一点区别
JavaScript中单引号和双引号的效果的一点区别
|
2月前
|
存储 前端开发 JavaScript
前端基础(三)_JavaScript数据类型(基本数据类型、复杂数据类型)
本文详细介绍了JavaScript中的数据类型,包括基本数据类型(Number、String、Boolean、Undefined、Null)和复杂数据类型(Object),并解释了如何使用`typeof`操作符来识别变量的数据类型。同时,还讨论了对象、函数和数组等复杂数据类型的使用方式。
45 2