文章目录
一、js数据类型
基本数据类型(又称原始数据类型,共7种):
Number,String,Boolean,null,undefined,symbol,bigint(后两个为ES6新增)
引用数据类型(1种):
object
object:普通对象(object),数组对象(array),函数对象(function),正则对象,日期对象,Math数学函数对象等。
两种数据存储方式:
基本数据类型是直接存储在栈中的简单数据段,占据空间小、大小固定
,属于被频繁使用的数据。栈是存储基本类型值和执行代码的空间。
引用数据类型是存储在堆内存中,占据空间大、大小不固定
。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址,当解释器寻找引用值时,会检索其在栈中的地址,取得地址后从堆中获得实体。
两种数据类型的区别:
1.堆比栈空间大,栈比堆运行速度快。
2. 堆内存是无序存储,可以根据引用直接获取。
3. 基础数据类型比较稳定,而且相对来说占用的内存小。
4. 引用数据类型大小是动态的,而且是无限的。
二、js判断数据类型的方法
1.typeof
通常用来判断基本数据类型,它返回表示数据类型的字符串
(返回结果只能包括number, string, boolean, undefined, object,function);
注意:使用typeof来判断null 返回的结果是 ‘object’,使用typeof来判断函数返回的结果是 ‘function’
console.log(typeof 1) //number
console.log(typeof '1') //string
console.log(typeof true) //boolean
console.log(typeof undefined) //undefined
console.log(typeof Symbol()) //symbol
console.log(typeof null) //object
console.log(typeof new Function()) //function
console.log(typeof [1,2,3]) //object
console.log(typeof {}) //object
console.log(typeof new Function()) //function
console.log(typeof new Date()) //object
2.instanceof
注意:instanceof 后面一定要是对象类型
console.log([1,2,3] instanceof Array) //true
console.log(new Date() instanceof Date) //true
console.log(new Function() instanceof Function) //true
console.log(null instanceof Object) //true
3.对象原型链判断方法: Object.prototype.toString.call()
适用于所有类型的判断检测
Object.prototype.toString.call("123") //'[object String]'
console.log(Object.prototype.toString.call("123")) //[object String]
console.log(Object.prototype.toString.call(123)) //[object Number]
console.log(Object.prototype.toString.call(null)) //[object Null]
console.log(Object.prototype.toString.call(undefined)) //[object Undefined]
console.log(Object.prototype.toString.call(true)) //[object Boolean]
console.log(Object.prototype.toString.call(Symbol())) //[object Symbol]
console.log(Object.prototype.toString.call({})) //[object Object]
console.log(Object.prototype.toString.call(function () {})) //[object Function]
4.根据constructor判断
let num = 1
let str = 'aaa~'
let boolean = true
let undef = undefined;
let nul = null;
let date = new Date()
let fn = function () {console.log('哈哈~');};
console.log(num.constructor.name) //Number
console.log(str.constructor.name) //String
console.log(boolean.constructor.name) //Boolean
console.log(date.constructor.name) //Date
console.log(fn.constructor.name) //Function
// console.log(undef.constructor.name) //Cannot read property "constructor" of undefined
// console.log(nul.constructor.name) //Cannot read property "constructor" of undefined
这种方式解决了instanceof的弊端,可以检测出除了undefined和null的9种类型
(因为它两没有原生构造函数)
三、为什么typeof null的结果是object
因为在JavaScript中,不同的对象都是使用二进制存储的
,如果二进制前三位都是0的话,系统会判断为是Object类型,而null的二进制全是0,自然也就判断为object
这个bug是初版本的JavaScript中留下的,扩展一下其他五种标识位:
-000
对象
-1
整型
-010
双精度类型
-100
字符串
-110
布尔类型
四、null和undefined的区别
undefined 的字面意思就是:未定义的值 。这个值的语义是,希望表示一个变量最原始的状态,而非人为操作的结果 。 这种原始状态会在以下 4 种场景中出现:
1.声明了一个变量,但没有赋值
2. 访问对象上不存在的属性
3. 函数定义了形参,但没有传递实参
4. 使用 void 对表达式求值
//1.声明了一个变量,但没有赋值
var foo;
console.log(foo) //undefined
//2.访问对象上不存在的属性
console.log(Object.foo) //undefined
//3.函数定义了形参,但没有传递实参
function fn(a) {
console.log(a)
}
fn(); //undefined
//4.使用 void 对表达式求值
console.log(void 0) //undefined
console.log(void false) //undefined
console.log(void []) //undefined
console.log(void null) //undefined
console.log(void function fn() {}) //undefined
因此,undefined 一般都来自于某个表达式最原始的状态值,不是人为操作的结果。当然,你也可以手动给一个变量赋值 undefined,但这样做没有意义,因为一个变量不赋值就是 undefined 。
null 的字面意思是:空值 。这个值的语义是,希望表示一个对象被人为的重置为空对象,而非一个变量最原始的状态 。 在内存里的表示就是,栈中的变量没有指向堆中的内存对象
null 有属于自己的类型 Null,而不属于Object类型,typeof 之所以会判定为 Object 类型,是因为JavaScript 数据类型在底层都是以二进制的形式表示的,二进制的前三位为 0 会被 typeof 判断为对象类型,而 null 的二进制位恰好都是 0 ,因此,null 被误判断为 Object 类型。