基础数据类型--JS

127 阅读4分钟

引言:

在 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

能判断numberstring,boolean,Symbol,function,undefinedBigInt,不能区分Objectnull 返回值为对应数据类型的字符串形式,而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