基本类型:
- Number
- String
- Boolean
- Null
- Undefined
- Symbol
- BigInt
null:表示"无"的对象,转为数值时为0;表示一个值被定义了,但是这个值是空值
- 作为函数的参数,表示函数的参数不是对象
- 作为对象原型链的终点 (Object.getPrototypeOf(Object.prototype))
- 定义一个值为null是合理的,但定义为undefined不合理(var name = null)
undefined:表示"无"的原始值,转为数值时为NaN;表示"缺少值",就是此处应该有一个值,但是还没有定义
- 变量被声明了还没有赋值,就为undefined
- 调用函数时应该提供的参数还没有提供,该参数就等于undefined
- 对象没有赋值的属性,该属性的值就等于undefined
- 函数没有返回值,默认返回undefined
引用类型:
- Object:Object、Array、Function、Data等
数据类型判断
- typeof:可以判断除
null
以外的基本类型 - instanceof:检测的是原型;只能用来判断两个对象是否属于实例关系 , 而不能判断一个对象实例具体属于哪种类型
instanceof
操作符可以正确判断出引用类型的类型。instanceof
本质上是判断右边的构造函数的prototype
对象是否存在于左边的原型链上,是的话返回true。所以不论数组、对象还是函数,... instanceof Object
都返回true
。
- constructor
-
null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。
-
函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object
为什么变成了 Object?
因为 prototype 被重新赋值的是一个 { }, { } 是 new Object() 的字面量,因此 new Object() 会将 Object 原型上的 constructor 传递给 { },也就是 Object 本身。
因此,为了规范开发,在重写对象原型时一般都需要重新给 constructor 赋值,以保证对象实例的类型不被篡改。
- 全能型判断类型方法:
Object.prototype.toString.call(...)
toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。
对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。
Object.prototype.toString.call(''); // [object String]
Object.prototype.toString.call(1); // [object Number]
Object.prototype.toString.call(true); // [object Boolean]
Object.prototype.toString.call(Symbol()); // [object Symbol]
Object.prototype.toString.call(undefined); // [object Undefined]
Object.prototype.toString.call(null); // [object Null]
Object.prototype.toString.call(new Function()); // [object Function]
Object.prototype.toString.call(new Date()); // [object Date]
Object.prototype.toString.call([]); // [object Array]
Object.prototype.toString.call(new RegExp()); // [object RegExp]
Object.prototype.toString.call(new Error()); // [object Error]
Object.prototype.toString.call(document); // [object HTMLDocument]
Object.prototype.toString.call(window); //[object global] window 是全局对象 global 的引用
强制类型转换
基本类型的相等性比较的是值是否一样,对象相等性比较的是内存地址是否相同。
对于[]
{}
function (){}
这样的没有被赋值给变量的引用类型来说,他们只在当前语句中有效,而且不相等于其他任何对象。因为根本无法找到他们的内存地址的指针。所以[] == []
是false
。
[] == ![] // true
/*
* 首先,布尔操作符!优先级更高,所以被转变为:[] == false
* 其次,操作数存在布尔值false,将布尔值转为数字:[] == 0
* 再次,操作数[]是对象,转为原始类型(先调用valueOf(),得到的还是[],再调用toString(),得到空字符串''):'' == 0
* 最后,字符串和数字比较,转为数字:0 == 0
*/
NaN == NaN // false NaN不等于任何值
null == undefined // true
null == 0 // false
undefined == 0 // false