前端面试之JavaScript -- JS中如何检测一个变量是什么类型

JS标准文档定义的类型

序号[[Class]]变量声明
01Arrayvar arr = [1,2,3,4];
02Booleanvar bool = true;
03Datevar date = new Date();
04Errorvar err = new Error();
05Functionvar func = function(){console.log(‘this is function’);}
06JSON{name:“苏”,age:25};
07Mathvar pi = Math.PI;
08Undefinedvar und = undefined;
09Nullvar nul = null;
10Numbervar num = 123;
11Objectvar obj = Object();
12RegExpvar reg = / ^ [a-zA-Z]{5,20}$ /;
13Stringvar str = “abcdef”;

不同的检测方案

1、不完全准确的检测:typeof

//以string类型为例
var str = "abcdef";
//获取变量obj类型
typeof(str); //"string"
typeof str;  //"string"
str.constructor;  //ƒ String() { [native code] }
//检测变量obj是否为string类型
typeof(str) === 'string'; //true
typeof str=== 'string';  //true
---- typeof 检测出的类型
判断类型typeof 判断结果
numnumber
strstring
boolboolean
arrobject
jsonobject
funcfunction
undundefined
nullobject
dateobject
regobject
errorobject

优点:使用简单,能直接输出结果
缺点:检测出的类型太少,不能检测出object的具体类型

2、不完全准确的检测:instanceof

//instanceof用于识别正在处理的对象(Object)类型
function Person(){}
function Student(){}
Student.prototype = new Person();
var Tom = new Student();
console.log(Tom instanceof Person); //true
console.log(Tom instanceof Student); //true
---- instanceof 检测出的类型
变量检测语句结果
var num = 123;num instanceof Numberfalse
var num = new Number(123);num instanceof Numbertrue
var str = “abcdef”;str instanceof Stringfalse
var str = new String(“abcdef”);str instanceof Stringtrue
var bool = true;bool instanceof Booleanfalse
var bool = new Boolean(true);bool instanceof Booleantrue
var arr = [1,2,3,4];arr instanceof Arraytrue
{name:“苏”,age:25};json instanceof Objecttrue
var func = function(){console.log(‘this is function’);}func instanceof Functiontrue
var und = undefined;und instanceof Objectfalse
var nul = null;nul instanceof Objectfalse
var date = new Date();date instanceof Datetrue
var reg = / ^ [a-zA-Z]{5,20}$ /;reg instanceof RegExptrue
var err = new Error();err instanceof Errortrue

优点:明确地确认对象(object)为某个特定类型;能检测出多层继承的关系
缺点:对number、string、boolean类型的变量声明方式有要求,必须用new方法声明才能检测,不能跨iframe

3、不完全准确的检测:constructor

var str = "abcdef";
str.constructor === String; //true
//输出数字类型变量的构造函数
var num = 123;
console.log(num.constructor); //function Number() { [native code] }
---- constructor 检测出的类型
变量检测语句结果
var Tom = new Person();Tom.constructor == Persontrue
var num = 123;num.constructor == Numbertrue
var str = “abcdef”;str.constructor == Stringtrue
var bool = true;bool.constructor == Booleantrue
var arr = [1,2,3,4];arr.constructor == Arraytrue
{name:“苏”,age:25};json.constructor == Objecttrue
var func = function(){console.log(‘this is function’);}func.constructor == Functiontrue
var date = new Date();date.constructor == Datetrue
var reg = / ^ [a-zA-Z]{5,20}$ /;reg.constructor == RegExptrue
var err = new Error();err.constructor == Errortrue

constructor:是原型对象的属性,指向构造函数,但根据实例对象寻找属性的顺序,如果实例对象上没有属性或方法时,就可以到原型链上寻找,所以实例对象也能使用constructor属性

优点:除了undefined和null,其他类型的变量都可以使用constructor检测
缺点:constructor属性可以被修改,会导致结果不正确,不能跨iframe

function Person(){}
function Student(){}
Student.prototype = new Person();
//Student原型中的constructor被指向到Person
var John = new Student();
console.log(John.constructor == Student);
console.log(John.constructor == Person);
//所以constructor检测不出实例对象John真实的构造函数

4、准确的检测:Object.prototype.toString.call

变量检测语句结果
var num = 123;Object.prototype.toString.call(num)‘[object Number]’
var str = “abcdef”;Object.prototype.toString.call(str)‘[object String]’
var bool = true;Object.prototype.toString.call(bool)‘[object Boolean]’
var arr = [1,2,3,4];Object.prototype.toString.call(arr)‘[object Array]’
{name:“苏”,age:25};Object.prototype.toString.call(json)‘[object Object]’
var func = function(){console.log(‘this is function’);}Object.prototype.toString.call(func)‘[object Function]’
var und = undefined;Object.prototype.toString.call(und)‘[object Undefined]’
var nul = null;Object.prototype.toString.call(nul)‘[object Null]’
var date = new Date();Object.prototype.toString.call(date)‘[object Date]’
var reg = / ^ [a-zA-Z]{5,20}$ /;Object.prototype.toString.call(reg)‘[object RegExp]’
var err = new Error();Object.prototype.toString.call(err)‘[object Error]’

Object.prototype.toString先取得对象的内部属性[[Class]],然后依据这个属性返回一个类似于"[Object Array]"的字符串作为结果,再配合call可以取得任何对象的内部属性,然后把类型检测转化为字符串比较。
优点:能检测出所有的类型
缺点:IE6下undefined、null均为Object类型

5、使用JQuery中的检测:$.type

变量检测语句结果
var num = 123;$.type(num)‘number’
var str = “abcdef”;$.type(str)‘string’
var bool = true;$.type(bool)‘boolean’
var arr = [1,2,3,4];$.type(arr)‘array’
{name:“苏”,age:25};$.type(json)‘object’
var func = function(){console.log(‘this is function’);}$.type(func)‘function’
var und = undefined;$.type(und)‘undefined’
var nul = null;$.type(nul)‘null’
var date = new Date();$.type(date)‘date’
var reg = / ^ [a-zA-Z]{5,20}$ /;$.type(reg)‘regexp’
var err = new Error();$.type(err)‘error’

可以看出,JQuery中的$ .type的输出结果和Object.prototype.toString.call的输出结果很像,因为$.type就是用Object.prototype.toString.call实现的。

总结

  1. Number、String、Boolean 类型变量的检测:typeof
  2. Array、JSON、Function、Undefined、Null、Date、RegExp、Error 等 Object 和 Function 类型变量的检测:推荐使用Object.prototype.toString.call 以及 $.type
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值