JS -- (1) 数据类型(略)与其的检测判断

53 阅读3分钟

一. 数据类型

JS8 种数据类型。其中包括 7 种简单数据类型(原始数据类型)、1 种复杂数据类型(引用数据类型)。

<1> 简单数据类型(原始数据类型)
  • number
  • string
  • boolean
  • undefined
  • null
  • symbol
  • bigInt

其中,symbolbigInt都是 ES6 新增的数据类型。

symbol的出现是为了解决全局变量命名冲突的问题!!

bigInt是一种 number 类型的数据,它可以表示任意精度格式的整数,使用它可以安全地存储和操作大整数!!即使该数已经超出了 number 能够表示的安全整数范围!!!

<2> 复杂数据类型(引用数据类型)
  • object
<3> 两种数据类型(简单 and 复杂)在内存中的存储位置

原始数据类型(简单) 存储在中,占据空间小、大小固定、会被频繁使用。

引用数据类型(复杂) 存储在中,占据空间大,大小不固定。如果存储在栈中,会影响程序运行的性能!!!引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。 当解释器寻找引用值时,会先检索其在栈中的地址,取得地址后从堆中获得实体!!!

栈和堆的区别有:

  • 栈区内存由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
  • 堆区内存一般由开发者分配释放,若开发者不释放,程序结束时可能由垃圾回收机制回收。

二. 检测类型的方法

<1> typeof

7 个返回值,且返回值是以字符串的形式返回!!!【少 null 、bigInt,多 function

  • "number"
  • "string"
  • "boolean"
  • "undefind"
  • "symbol"
  • "object"
  • "function"

注意:

  • 该方法,不能区分 object 和 null ,即 typeof null 返回的也是 "object"
<2> instanceof 只能判断引用数据类型,不能判断基本数据类型

A instanceof B其内部的运行机制就是判断在 A 的原型链中能否找到 B 的原型。 因为只有引用数据类型才会有原型链,所以 instanceof 只能用来判断引用数据类型!!!

2126.png

instanceof实现原理:

2127.png

其中getPrototypeOf() 方法来获得实例的原型对象!!

<3> constructor (限制过多且容易出错,少用!!!)

constructor的作用:

  • 原型对象 or 对象实例通过 constructor 方法访问它的构造函数。
  • 判断数据的类型

注意:

  • constructor__proto__ 属性是对象特有的
  • prototype属性是函数特有的
  • 所以函数有constructor__proto__prototype三种属性

所以,除了基本引用类型,一些特 JS 内置的对象还有原始值包装类型的对象都有constructor__proto__ 属性!!!

2128.png

  • 前三个 ,按理说 2 、true 、'str' 都属于原始值类型,按理说是不能用 constructor 方法进行检验的!!!但看结果好像成功了,是因为它们加了括号()!!
  • (1) 等价于 Number(1) ,只不过省略了前面的具体化数据类型 Number
  • Number(1) 和 1 可就大不一样了, Number(1)是对 1 的装箱!!!装箱过后就变成了原始值包装类型,它身上就有constructor__proto__ 属性了!!
<4> Object.prototype.toString.call() 基本上能判断所有的数据类型(自定义数据类型除外)

注意:

使用的是 Object 原型上的 toString 方法 ,而不是要检测的东西上的 toString 方法,因为像 Array、function等类型作为 Object 的实例都重写了 toString 方法, 所以如果直接在数组实例上调用 [ 1 , 2 , 3 ].toString() ,那么得到的是该数组元素组成的字符串!!!!

该方法返回的是 [ object 类型 ] 格式的字符串

console.log(Object.prototype.toString.call(2))
console.log(Object.prototype.toString.call(true))
console.log(Object.prototype.toString.call(function(){}))

结果如下:

2129.png

三. 判断数组的方法有哪些?

let arr = [ 1 , 2 , 3]

判断如下:

  • instanceof
arr instanceof Array // true
  • Object.prototype.toString.call()
Object.prototype.toString.call(arr)  // [object Array]
Object.prototype.toString.call(arr).slice(8,-1) // Array
  • 构造函数 Array 原型对象上的方法:Array.prototype.isPrototypeOf()
Array.prototype.isPrototypeOf(arr) // true
  • Array 上的方法:Array.isArray()
Array.isArray(arr)  // true