【JavaScript基础】数据类型的判断方法

122 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情

typeof

typeof 检测变量的数据类型,返回的是表示该类型的字符串。

对于基本数据类型,除了null返回的是object,其它都可以返回正确类型;

对于引用数据类型(对象)来说,除了函数返回的是function,其它都返回object,因此使用typeof无法正确判断引用数据类型

console.log(typeof 2);               // number
console.log(typeof true);            // boolean
console.log(typeof 'str');           // string
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object     null 的数据类型被 typeof 解释为 object
-----------------------------------------------------------------
console.log(typeof []);              // object     []数组的数据类型在 typeof 中被解释为 object
console.log(typeof function(){});    // function
console.log(typeof {});              // object

instanceof

instanceof 返回一个布尔值。用来判断对象的类型,原理是检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。也就是判断对象是否是某一数据类型(如Array)的实例

instanceof不适用于判断基本数据类型,始终返回false

object instanceof constructor
//object  某个实例对象
//constructor  某个构造函数

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false  
----------------------------------------------------------------
//引用数据类型的值都是object的实例,在检测一个引用类型值和Object构造函数时,instanceof操作符始终返回true。
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true

Object.prototype.toString()

Object.prototype.toString()方法是Object 对象的原型方法, 返回对象的类型字符串'[object Object]',第二个Object表示该值的数据类型。

基本数据类型需要使用函数的call或者apply方法对基本数据类型进行包装才能正确判断。

Object.prototype.toString()方法适用于判断所有数据类型

//结果都为true
Object.prototype.toString.call({})  ===  '[object Object]'   
Object.prototype.toString.call([])   ===  '[object Array]'  
Object.prototype.toString.call(() => {})  ===  '[object Function]'  
Object.prototype.toString.call('somestring')  ===  '[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(null)   ===  '[object Null]'  
Object.prototype.toString.call(undefined)  === '[object Undefined]' 

扩展:call 和 apply

call 和 apply 实现函数调用,将一个对象的方法交给另一个对象来执行,并且是立即执行的,都可以改变 this 的指向。作用都是相同的,只是传参的方式不同。

call的写法: function.call(thisArg, arg1, arg2, ...)

  • 调用 call 的对象,必须是个函数
  • 第一个参数为目标对象外,第二个参数开始可以接收一个参数列表 Object.prototype.toString()方法适用于判断所有的数据类型

apply的写法: function.apply(thisArg , [ argsArray])

  • 调用 apply 的对象,必须是个函数
  • 只接收两个参数,第一个参数为目标对象外,第二个参数只接受一个包含多个参数的数组。

constructor属性

constructor是prototype对象上的属性,指向prototype对象所在的构造函数。null和undefined没有constructor存在,因此使用constructor无法判断。

//number、string、boolean三种数据类型有对应的Number、String、Boolean三个原生对象(包装对象)。因此,也可用 `constructor`进行判断
console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true

console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true

----------------------------------------------------------
function Fn(){};
Fn.prototype=new Array();
var f=new Fn();
console.log(f.constructor===Fn);    // false,函数Fn的原型改变了,constructor也会发生改变
console.log(f.constructor===Array); // true 

注:constructor 属性可准确的判断对象实例是由哪个构造函数生成的,但如果修改了原型对象prototype,会造成constructor属性指向不准确。