数据类型:基本类型、引用类型以及类型判断方法

763 阅读3分钟

基本类型:

  • 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

1635402462772.jpg

  1. null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。

  2. 函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object

image.png

为什么变成了 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