JS的数据类型分为基础类型和引用类型2种
基础类型:Number、String、Undefined、null、Boolen、Symbol、BigInt
Symbol:用于创建一个独一无二且不可变的数据类型,它主要是为了解决可能出现的全局变量冲突问题。
BigInt:是一种数字类型的数据,它可以表示任意精度格式的整数,使用BigInt可以安全地存储和操作大整数,即使这个数已经超出了Number能够表示的安全整数范围。在JavaScript 中Number.MAX_SAFE_INTEGER 表示最⼤安全数字,计算结果是9007199254740991,即在这个数范围内不会出现精度丢失(⼩ 数除外)。但是⼀旦超过这个范围,js 就会出现计算不准确的情况, 这在⼤数计算的时候不得不依靠⼀些第三⽅库进⾏解决,因此官⽅提 出了 BigInt 来解决此问题。
引用类型:Object、Array、Function、RegExp、Date、Math
存储关系
基础类型存储在栈内存,被引用或拷贝时,会创建一个完全相等的变量;
引用类型存储在堆内存,会在栈内存中存储引用类型的堆地址,多个引用指向同一个地址,这里会涉及一个“共享”的概念。
let a = {
name: 'lee',
age: 18
}
let b = a;
console.log(a.name); //第一个console
b.name = 'son';
console.log(a.name); //第二个console
console.log(b.name); //第三个console
第一个 console 打出来 name 是 'lee',这应该没什么疑问;但是在执行了 b.name='son' 之后,结果你会发现 a 和 b 的属性 name 都是 'son',第二个和第三个打印结果是一样的,这里就体现了引用类型的“共享”的特性,即这两个值都存在同一块内存中共享,一个发生了改变,另外一个也随之跟着变化。
let a = {
name: 'Julia',
age: 20
}
function change(o) {
o.age = 24;
o = {
name: 'Kath',
age: 30
}
return o;
}
let b = change(a);
思考:第一个console.log和第二个console.log分别输出什么?为什么?
console.log(b.age); // 第一个console
console.log(a.age); // 第二个console
第一个 console 的结果是 30,b 最后打印结果是 {name: "Kath", age: 30};第二个 console 的返回结果是 24,而 a 最后的打印结果是 {name: "Julia", age: 24}。
原因在于:函数传参进来的 o,传递的是对象在堆中的内存地址值,通过调用 o.age = 24(确实改变了 a 对象的 age 属性;把参数 o 的地址重新返回了,将 {name: "Kath", age: 30} 存入其中,最后返回 b 的值就变成了 {name: "Kath", age: 30}。而如果把第 12 行去掉,那么 b 就会返回 undefined。这里你可以再仔细琢磨一下。
String的存储位置?
String是没有长度限制的,所以它是动态存储的,先确认了String的大小再决定是存在栈中还是堆中。
null 和 undefined 区别?
首先 Undefined 和 Null 都是基本数据类型,这两个基本数据类型 分别都只有一个值,就是 undefined 和 null。
undefined 代表的含义是未定义,null 代表的含义是空对象。一般变量声明了但还没有定义的时候会返回 undefined,null 主要用于 赋值给一些可能会返回对象的变量,作为初始化。
undefined 在 JavaScript 中不是一个保留字,这意味着可以使用 undefined 来作为一个变量名,但是这样的做法是非常危险的,它会 影响对 undefined 值的判断。我们可以通过一些方法获得安全的 undefined 值,比如说 void 0。
当对这两种类型使用 typeof 进行判断时,Null 类型化会返回 “object”,这是一个历史遗留的问题。当使用双等号对两种类型的 值进行比较时会返回 true,使用三个等号时会返回 false。而typeof undefined为undefined字符串。typeof undefined ==="undefined" 为true。