js类型判断的方法(JS的基本类型共有三种)

js类型判断的方法(JS的基本类型共有三种)

面试季马上就要过去了,很多小伙伴也是在努力的抓住金九银十的小尾巴,今天来说一说面试中常见的一个问题:js中如何判断数据类型?

众所周知,JavaScript是一门弱类型的语言,它允许不兼容的类型进行运算,但有些场景使得我们不得不对数据类型做一个规范,如此就需要对数据类型进行判断。

可能你会回答,我一般用typeof来进行判断,可是面试官会问你,那如果遇到值为null的情况下typeof会返回什么?对于初入江湖的新手来说可能在这个时候就败下阵来,没错,我当初也是这样,判断数据为null或者undefined不是用if-else来判断的吗?

带着疑问,接下来我们就来看一下如何判断数据类型:

typeof

在此引用MDN的说明:

typeof 操作符返回一个字符串,表示未经计算的操作数的类型。

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

示例:

console.log(typeof333);//numberconsole.log(typeoftrue); //booleanconsole.log(typeof’aaa’);//stringconsole.log(typeof []); // object []数组的数据类型在 typeof 中被解释为 objectconsole.log(typeof function(){}); // functionconsole.log(typeof {}); // objectconsole.log(typeof undefined); // undefinedconsole.log(typeof null); // object null 的数据类型被 typeof 解释为 objectnull// JavaScript 诞生以来便如此typeof null === ‘object’;

在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于null代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null也因此返回”object”。

曾有一个 ECMAScript 的修复提案(通过选择性加入的方式),但被拒绝了。该提案会导致typeof null === ‘null’。

错误:

在 ECMAScript 2015 之前,typeof总能保证对任何所给的操作数返回一个字符串。即便是没有声明的标识符,typeof也能返回’undefined’。使用typeof永远不会抛出错误。

但在加入了块级作用域的let和const之后,在其被声明之前对块中的let和const变量使用typeof会抛出一个ReferenceError。块作用域变量在块的头部处于“暂存死区”,直至其被初始化,在这期间,访问变量将会引发错误。

typeof undeclaredVariable === ‘undefined’;typeof newLetVariable; // ReferenceErrortypeof newConstVariable; // ReferenceErrortypeof newClass; // ReferenceErrorlet newLetVariable;const newConstVariable = ‘hello’;class newClass{};

instanceof

依然引用MDN的说明:

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

示例:

console.log(333instanceofNumber);//falseconsole.log(true instanceof Boolean); // false console.log(‘aaa’instanceofString);//falseconsole.log([] instanceof Array); // trueconsole.log(function(){} instanceof Function); // trueconsole.log({} instanceof Object); // true

以上结果显示,直接的字面量值判断数据类型,只有引用数据类型(Array,Function,Object)被精准判断,其他(Number,Boolean,String)字面值不能被instanceof精准判断。

需要注意的是,如果表达式obj instanceof Foo返回true,则并不意味着该表达式会永远返回true,因为Foo.prototype属性的值有可能会改变,改变之后的值很有可能不存在于obj的原型链上,这时原表达式的值就会成为false。另外一种情况下,原表达式的值也会改变,就是改变对象obj的原型链的情况,虽然在目前的ES规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的__proto__伪属性,是可以实现的。比如执行obj.__proto__ = {}之后,obj instanceof Foo就会返回false了。

到这里大家可能已经观察到了,为什么我在上面的示例中没有用instanceof来判断null和undefined,我们在浏览器中输出一下看是什么结果:

浏览器在这里报错了,它认为null,undefined不是构造器。

Object.prototype.toString.call()

最后,留到最后的才是最好的,我们来看一下终极大招:

Object.prototype.toString.call()

MDN中说明:

toString()方法返回一个表示该对象的字符串。

每个对象都有一个toString()方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString()方法被每个Object对象继承。如果此方法在自定义对象中未被覆盖,toString()返回”[objecttype]”,其中type是对象的类型。以下代码说明了这一点:

var o = new Object();o.toString(); // returns [object Object]

可以通过toString()来获取每个对象的类型。为了每个对象都能通过Object.prototype.toString()来检测,需要以Function.prototype.call()或者Function.prototype.apply()的形式来调用,传递要检查的对象作为第一个参数,称为thisArg。

var toString = Object.prototype.toString;toString.call(333); // [object Number]toString.call(“aaa”);//[object String]toString.call(true);// [object Boolean]toString.call([]);// [object Array]toString.call(function(){});//[object Function]toString.call({});//[objectObject]toString.call(undefined);//[objectUndefined]toString.call(null); // [object Null]// 甚至于js的内置对象也能被精确判断toString.call(newDate);//[objectDate]toString.call(new String); // [object String]toString.call(Math); // [object Math]

相信到这里你已经知道该如何回答面试官的问题了吧

文末彩蛋

大家好,我是亚北,也就是博主各大粉丝群中的小助理,今天心血来潮想写一篇文章给老大来投稿,好吧,其实是她嫌我不思进取?可能吧。于是我翻了几道常见的面试题,最后选择了这道,可能很常见,但是也容易被忽略,比如要不是今天查资料,我就不知道Object.prototype.toString.call()还可以判断Date,Math等js内置对象类型。最后希望大家都可以在面试季中拿到自己心仪公司的offer,人均大厂,年薪百万!

跟着前端Q学前端,大厂始终近你一步!

最后

发表评论

登录后才能评论