引言:
在 JS 中共有
8种基础的数据类型,分别为:Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt。
一、Symbol 和 BigInt :
!!!
Symbol和BigInt是 ES6 新增的数据类型,可能会被单独问:
1、BigInt 是一种内置对象,可以表示任意大小的整数:
- 1.创建方法:BigInt 是通过在
整数末尾附加字母 n或调用构造函数(不需要new)来创建的 - 2.作用:通过引入 BigInt,您可以操作超过 Number.MAX_SAFE_INTEGER 的大整数
// 创建
let x = BigInt(Number.MAX_SAFE_INTEGER);
console.log(x); // 9007199254740991n
// 使用
console.log(x + 1n === x + 2n); // false
console.log(x + 1n); // 9007199254740992n
console.log(x + 2n); // 9007199254740993n
- 可以对 BigInt 使用运算符
+、*、-、** 和 %,就像对数字一样。BigInt 严格来说并不等同于一个数字,但它也同样可以轻松地使用。 - 再将 BigInt 转换为 Boolean 时(例如:
if、||、&&、Boolean 和 !),它的行为类似于一个数字。 - 不能用于
Math对象中的方法; - BigInt 不能与
Number类型相互运算。否则,将抛出 TypeError。 - BigInt 变量在转换成Number变量时可能会丢失精度。
2、Symbol 代表独一无二的值,最大的用法是用来定义对象的唯一属性名。
symbol 是一种基本数据类型([primitive data type])。
Symbol()函数会返回 symbol 类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的 symbol 注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:"new Symbol()"。--MDN JavaScript标准内置对象--Symbol
二、原始数据和引用数据
1、数据分类及它们的存储位置
- 栈:原始数据类型(Undefined、Null、Boolean、Number、String、Symbol和BinInt)
- 栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储。
- 堆:引用数据类型(Object)(对象、数组和函数)
- 堆(heap)中的对象,占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针(地址值),该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
2、堆和栈
堆和栈的概念存在于数据结构中和操作系统内存中。
1.在数据结构中:
- 栈中的数据存取都是按照先进后出的原则,类似于子弹和弹夹的关系;
- 堆是一个优先队列,是按优先级来进行排序的,优先级可以按照大小来规定。
2.在操作系统中,内存被分为栈区和堆区。
- 栈区内存由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
- 堆区内存一般由程序员分配释放,若程序员不释放,程序结束时可能由垃圾回收机制回收。
三、数据类型的判断
1、typeof
能判断
number,string,boolean,Symbol,function,undefined和BigInt,不能区分Object和null返回值为对应数据类型的字符串形式,而Object和null都返回object
// 能判别
console.log(typeof 2); // number
console.log(typeof 'str'); // string
console.log(typeof true); // boolean
console.log(typeof Symbol('foo')); // symbol
console.log(typeof function () {}); // function
console.log(typeof undefined); // undefined
console.log(typeof 10086111586n); // bigint
// 不能判别
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof null); // object
console.log(typeof Math); // object
console.log(typeof Date); // function
console.log(typeof RegExp); // function
console.log(typeof Object); // function
console.log(typeof Array); // function
console.log(typeof String); // function
构造函数也都会返回function,Date\RegExp\Object\Array\String等等 Math是对象
2、instanceof
能判断对象类型,不能判断基本数据类型,其内部运行机制是判断在其原型链中能否找到该类型的原型。 其实现就是顺着原型链去找,如果能找到对应的
Xxxxx.prototype就返回true。
console.log({} instanceof Object); // true
console.log(null instanceof Object); // false
function a() {}
console.log(a instanceof Function); // true
3、Object.prototype.toString.call() :所有原始数据类型都是能判断的,
console.log(Object.prototype.toString.call(2)); // "[object Number]"
console.log(Object.prototype.toString.call('')); // "[object String]"
console.log(Object.prototype.toString.call(true)); // "[object Boolean]"
console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
console.log(Object.prototype.toString.call(null)); // "[object Null]"
console.log(Object.prototype.toString.call(Math)); // "[object Math]"
console.log(Object.prototype.toString.call(Date));// [object Function]
console.log(Object.prototype.toString.call({})); // "[object Object]"
console.log(Object.prototype.toString.call([])); // "[object Array]"
console.log(Object.prototype.toString.call(function () {})); // "[object Function]"
console.log(Object.prototype.toString.call(Symbol('foo'))); // "[object Symbol]"
console.log(Object.prototype.toString.call(10086111586n)); // "[object BigInt]"
拓展:如何判断变量是否为数组?
- 1、instanceof
- 2、Object.prototype.toString.call()
- 3、Array.isArray()
- 4、proto 属性
// 判断是否为数组的方式
let arr = [];
let obj = {};
console.log(arr instanceof Array); // true
console.log(Object.prototype.toString.call(arr)); // "[object Array]"
console.log(Array.isArray(arr)); // true
console.log(arr.__proto__ === Array.prototype); // true
console.log(obj instanceof Array); // false
console.log(Object.prototype.toString.call(obj)); // "[object object]"
console.log(Array.isArray(obj)); // false
console.log(obj.__proto__ === Array.prototype); // false