数据类型判断

295 阅读3分钟

null

在JavaScript中,null 是一种特殊的原始数据类型,它表示一个明确的“无”值或者说“空值”,通常用来表示变量尚未定义、已被释放或者意在指向某个对象但当前实际并未指向任何对象。虽然在历史上,typeof null 返回 "object",这是一个JavaScript语言设计上的历史遗留问题,并不意味着 null 是对象类型;实际上,null 不是对象,也不是函数,更不是数组,它就是 null 类型。

关于原型(prototype)与 null 的关系,在JavaScript中,每个对象都有一个内部链接指向它的原型,这个原型链是用来实现继承和查找属性的机制。原型链的顶端或者说终点就是一个特殊的值 null,表示没有更上层的原型了。当调用 Object.getPrototypeOf(someObject) 方法到达原型链的最顶层时,如果一个对象的原型已经是 null,那就意味着已经到达了原型链的终点,这个对象不再有其他的原型对象。

例如:

let obj = {};
console.log(Object.getPrototypeOf(obj)); // 输出:{} 即 Object.prototype

let objWithoutPrototype = Object.create(null);
console.log(Object.getPrototypeOf(objWithoutPrototype)); // 输出:null

在这段代码中,objWithoutPrototype 是通过 Object.create(null) 创建的一个没有原型的对象,因此它的原型就直接是 null

typeof

返回一个字符串,标识操作数类型

typeof operand

返回值

类型结果
Undefined"undefined"
Null"object"
Boolean"boolean"
Number"number"
BigInt"bigint"
String"string"
Symbol"symbol"
Function"function"
其他任何对象"object"

typeof null

typeof null === "object";

JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。
对象的类型标签是 0,null 代表的是空指针(大多数平台下值为 0x00),所以类型为"object"

new构造函数

所有使用new调用的构造函数都将返回非基本类型("object" 或 "function")。大多数返回对象。functionnew出来是"function"

typeof优先级高于运算,表达式需要加括号

未声明或初始化,返回"undefined"

instanceof

instanceof 运算符用来检测构造函数 constructor.prototype 是否存在于参数实例对象 object 的原型链上。

object instanceof constructor

String对象和Date对象是Object派生出来的特殊对象,不属于String类型

const myObj={}
myObj instanceof Object  // true

const myNonObj=Object.create(null)
myNonObj instanceof Object  // false

const simpleStr="This is a simple string"
simpleStr instanceof String  // false  非对象实例

const myString=new String("String created width constructor")
myString instanceof String  // true

const myDate=new Date()
myDate instanceof Date  // true
myDate instanceof Object  // true
myDate instanceof String  // false

基本类型使用typeof判断,对象类型使用instanceof判断

数组和对象类型的判断方法

在JavaScript中,要判断一个变量是对象类型还是数组类型,可以使用以下几种方法:

判断是否为对象(包括数组,因为数组也是对象的一个子类型):

  1. typeof 操作符

    if (typeof myVariable === 'object' && myVariable !== null) {
      // 如果不是 'undefined' 或 'null',则可能是对象或数组
    }
    
  2. instanceof 关键字

    if (myVariable instanceof Object) {
      // 是对象或其子类型,但不能直接区分对象和数组
    }
    

判断是否为数组:

  1. Array.isArray() 函数(推荐):
    if (Array.isArray(myVariable)) {
      // 是数组
    } else {
      // 不是数组,但仍可能是对象
    }
    

特殊情况判断对象是否为数组:

  1. Array.prototype.isPrototypeOf()

    if (Array.prototype.isPrototypeOf(myVariable)) {
      // 是数组
    }
    
  2. 构造函数检查

    if (myVariable.constructor === Array) {
      // 是数组
    }
    
  3. toString() 方法配合判断

    if (Object.prototype.toString.call(myVariable) === '[object Array]') {
      // 是数组
    }
    

总结:

为了准确地判断一个变量是普通对象还是数组,请优先使用 Array.isArray() 方法,这是最简洁且无歧义的方式。如果需要进一步确认是否为非数组的对象,则可以在排除掉数组的可能性之后,使用 typeof 结合 null 检查或者 instanceof Object 等方法。