还是一句老话,大厂看中的不仅是你高超的技术,反而更看重你的基础。所以我们不能只主攻算法和高级的用法,更应该注意一些基础,底层的基础。今天来带大家细说一下JavaScript中的数据类型。希望大家能从中收获些什么。
什么是数据类型???
在JavaScript中,数据类型是用来定义变量可以存储的数据种类。因为JavaScript是一种动态类型的语言,所以我们在声明变量时不需要明确它的数据类型,因为我们的引擎会根据赋给变量的值自动确定它的数据类型.
数据类型的种类
JavaScript的数据类型主要分为两类:简单数据类型(也叫原始数据类型) 和 复杂数据类型。
简单数据类型中含有:Number、String、Boolean、Null、Undefined、Symbol、Bigint
复杂数据类型中含有:Object
此时面试官问你:JavaScript一共有几种数据类型?
此时,高手会回答8种!
但是!高高手会回答7种
此时你可能会很懵:7+1不是等于8吗?为什么回答7更厉害呢?
这里就有一个细节了。
Number和Bigint
都属于一个类中,这个类就是Numeric
。这是一个很隐秘的细节,往往就是你和高手之间的差距。
简单数据类型了解
number
普通的咱们就不多说,我们只说细节和重点
ini 代码解读复制代码let a = 0.1;
let b = 0.2;
console.log(a+b);
大家应该都认为输出0.3吧。这里又有一个坑了:
此时输出的结果是这样的:这是为什么呢?
虽然类型名称叫number
可他却不擅长于计算。在JavaScript中,我们的计算方式是以二进制计算。当数字为小数时,在二进制中是无限循环的小数
-
0.1
的二进制表示大约是0.00011001100110011001100110011001100110011001100110011010
-
0.2
的二进制表示大约是0.0011001100110011001100110011001100110011001100110011010
此时相加便等于上面的结果。
Null
在我们的潜意识中,null的意思就是空
。但空值是不是也给一个变量赋值了呢?
答案是肯定的。
null是一个可以赋值给对象的一个特殊值。
ini 代码解读复制代码let a = null;
console.log(a);
此时输出
另外的,他还可以显示内存回收
javascript 代码解读复制代码// 堆内存
let largeObject={
data:new Array(100).fill('a')
}
// 释放内存 垃圾回收
largeObject=null;
语法咱们就不多说,fill把数组内都赋值为a。
但这就牵扯到一个新的问题。
栈内存和堆内存
简单来说
- 栈内存:
用于存储变量的名称和值(如果是基本类型)或引用(如果是对象)。
- 堆内存:
用于存储对象的实际数据。
ini 代码解读复制代码let a = 1;
// 拷贝
let b = a;
b=3;
console.log(a,b) // 1 3
图片来自稀土掘金技术社区
在上面代码中。我们先声明了一个变量largeObject
,此时变量存储在栈内存中。
然后,我们创建了一个对象data:new Array(100).fill('a')
,此时对象存储在堆内存中。
最后我们引用赋值:largeObject
存储的是指向堆内存中对象的引用
此时我们就进行了释放内存,垃圾回收的步骤
largeObject = null;
- 重新赋值:将
largeObject
重新赋值为null
。此时,栈内存中largeObject
的值从原来的引用变成了null
。
此时我们的堆内存中对象被孤立。垃圾回收器会在未来的某个时刻自动回收这些孤立对象,但这个过程是后台进行的,不会影响代码的输出
引用了对象中没有的属性:
javascript 代码解读复制代码let person = {
name: "John",
age: null
};
console.log(person.age); // 输出 null
undefined
有人可能认为,null和undefined很相似,都是表示无
或空
的特殊值。这是有道理的,但他们的语义和使用场景有一些重要的区别。
当我们引用声明了但未赋值的变量时:
javascript 代码解读复制代码let x;
console.log(x); // 输出 undefined
类似的未定义的属性:
ini 代码解读复制代码let obj = {};
console.log(obj.name); // 输出 undefined
函数参数未提供:
scss 代码解读复制代码function printName(name) {
console.log(name);
}
printName(); // 输出 undefined
symbol
symbol是es6后出现的数据类型,用于创建唯一的标识符。有函数一样的外观。
唯一性:即使描述的字符串相同,也会输出false
ini 代码解读复制代码let sym1 = Symbol("key");
let sym2 = Symbol("key");
console.log(sym1 === sym2); // 输出 false
boolean
表示真或假,值为 true
或 false
。
bigint
这个类型也是es6才引入的。用于处理数据过大的问题 当我们输入:
ini 代码解读复制代码let num = 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999;
let num2=41814854854854888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888844854451451442;
console.log(num+num2);
此时会出现
数值一点都不准确啊。
想让数值变得更准确,只需要在数据后加n,则创建了bigint类型,可以得到准确值
注意事项
- 类型检查:
BigInt
是一个独立的类型,不能与Number
类型直接进行比较或运算。
ini 代码解读复制代码let num = 1234567890123456789012345678901234567890;
let bigInt = 1234567890123456789012345678901234567890n;
console.log(num === bigInt); // 输出 false
复杂数据类型了解
object可以包含所有复杂数据类型,数组,函数,正则表达式等。这些都很常见,就不过多介绍了。
区别
简单数据类型与复杂数据类型有哪些区别?
简单数据类型 一眼就能看出其值
函数、数组等有很多特性无法表达
还有一个,简单数据类型进行的是值传递,直接储存在栈内存中,是不可改变的
复杂类型则是引用传递,数据存储在堆内存中,变量存储的是引用,可以改变
typeof
用typeof可以分析我们输入数据类型的类型。
javascript 代码解读复制代码console.log(typeof 1);
console.log(typeof "hello");
console.log(typeof true);
console.log(typeof 12n);
console.log(typeof Symbol());
console.log(typeof null);
console.log(typeof undefined);
console.log(typeof function(){})
此时输出:
typeof 除了null 之外的简单数据类型 都可以得到正确的结果
这是为什么呢?
这是因为JavaScript在最初设计时留下的bug。当时,null
被设计为表示空对象指针
,因此 typeof null
返回 "object"
是为了与 C/C++ 中的 NULL
指针保持一致。
为了保持兼容性,就一直这样使用了。
结语
这就是关于数据类型的一些说明,希望大家可以从中收获。
评论记录:
回复评论: