一. 数据类型
JS
有 8 种数据类型。其中包括 7 种简单数据类型(原始数据类型)、1 种复杂数据类型(引用数据类型)。
<1> 简单数据类型(原始数据类型)
- number
- string
- boolean
- undefined
- null
- symbol
- bigInt
其中,
symbol
和bigInt
都是 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 只能用来判断引用数据类型!!!
instanceof实现原理:
其中getPrototypeOf() 方法来获得实例的原型对象!!
<3> constructor (限制过多且容易出错,少用!!!)
constructor的作用:
- 原型对象 or 对象实例通过
constructor
方法访问它的构造函数。 - 判断数据的类型
注意:
constructor
和__proto__
属性是对象特有的prototype
属性是函数特有的- 所以函数有
constructor
、__proto__
、prototype
三种属性
所以,除了基本引用类型,一些特 JS 内置的对象还有原始值包装类型的对象都有
constructor
和__proto__
属性!!!
- 前三个 ,按理说 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(){}))
结果如下:
三. 判断数组的方法有哪些?
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