# 数据类型检测

# 操作符 typeof

# 语法

typeof运算符后跟操作数:

typeof operand
// or
typeof (operand)

# 返回值

下表总结了typeof可能的返回值

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

# 示例

// boolean
typeof true === 'boolean'
typeof false === 'boolean'
// undefined
typeof undefined ==='undefined'
// Number
typeof 37 === 'number';
typeof NaN === 'number';
typeof Math.PI === 'number';
// bigint
typeof 1n ==='bigint'
// String
typeof "" === 'string';
typeof "bla" === 'string';
typeof (typeof 1) === 'string'; // typeof总是返回一个字符串
// Object
typeof {a:1} === 'object';
typeof [1, 2, 4] === 'object';
typeof null === 'object';    //特殊值null被认为是一个空的对象引用

TIP

严格来讲,函数在 ECMAScript 中被认为是对象,并不代表一种数据类型。可是,函数也有自己特殊的属性。为此,就有必要通过 typeof 操作符来区分函数和其他对象。

# prototype

# 语法

Object.prototype.toString.call(x)   //[object x]

# 示例

console.log(Object.prototype.toString.call(new Date()))     // [object Date]
console.log(Object.prototype.toString.call(null)            // [object Null]
console.log(Object.prototype.toString.call(new Array()))    // [object Array]
console.log(Object.prototype.toString.call('dd'))           // [object String]
console.log(Object.prototype.toString.call(undefined))      // [object Undefined]
console.log(Object.prototype.toString.call(Symbol('d')))    // [object Symbol]
console.log(Object.prototype.toString.call(Function))       // [object Function]
console.log(Object.prototype.toString.call(1n))             // [object BigInt]

这种方法能够很好的检测出各种类型。

function isType(data,type){
    if(Object.prototype.toString.call(data) === "[object "+type+"]"){
        return true;
    }
    return false;
}

function isNumber(data){
    return isType(data,'Number');
}
function isBoolean(data){
    return isType(data,'Boolean');
}
function isString(data){
    return isType(data,'String');
}
function isUndefined(data){
    return isType(data,'Undefined');
}
function isNull(data){
    return isType(data,'Null');
}
function isSymbol(data){
    return isType(data,'Symbol');
}
function isArray(data){
    return isType(data,'Array');
}
function isFunction(data){
    return isType(data,'Function');
}
function isObject(data){
    return isType(data,'Object');
}
function isDate(data){
    return isType(data,'Date');
}
function isRegExp(data){
    return isType(data,'RegExp');
}

# 根据对象的constructor判断

在JavaScript中一切皆对象,每个对象都是某个构造函数的实例,因此具有constructor数据指向其构造函数,我们可以基于该特性来判断数据类型:

var num = 100;
num.constructor == Number   // Number 是数值构造函数

function isType(data,fn){
    return data.constructor === fn
}

isType(num,Number)     // true
isType('hello',String) // true
isType(true,Boolean)   // true
isType([],Array)       // true

# instanceof 运算符

在 JavaScript 中,判断一个变量的类型常常会用 typeof 运算符,在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 "object"。ECMAScript 引入了另一个 Java 运算符 instanceof 来解决这个问题。instanceof 运算符与 typeof 运算符相似,用于识别正在处理的对象的类型。

# instanceof 运算符的常规用法

使用 instanceof 就是判断一个对象是否是某个构造函数的实例。例如:

// 判断 foo 是否是 Foo 类的实例
function Foo(){}
var foo = new Foo();
console.log(foo instanceof Foo)//true

# instanceof 在继承中关系中的用法

instanceof 可以在继承关系中用来判断一个实例是否属于它的父构造函数。例如:

// 判断 foo 是否是 Foo 类的实例 , 并且是否是其父类型的实例
function Aoo(){}
function Foo(){}
Foo.prototype = new Aoo();//JavaScript 原型继承

var foo = new Foo();
console.log(foo instanceof Foo)//true
console.log(foo instanceof Aoo)//true

上面的代码中是判断了一层继承关系中的父类,在多层继承关系中,instanceof 运算符同样适用。

# 直接量不能使用instanceof

var a=1;

a instanceof Number;

//false

var b="123";

b instanceof String;

//false

直接量不能使用instanceof的。

instanceof的用途是判断一个对象是否在某个对象原型链上。或者说判断一个对象是某个构造函数的实例。