在前端笔试面试中“JS数据类型的分类和判断”是高频的基础考点,今天总结一下,对正在准备找工做的小伙伴应该有所帮助~ 前端
JavaScript中有6种数据类型:数字(number)、字符串(string)、布尔值(boolean)、undefined、null、对象(Object)。其中对象类型包括:数组(Array)、函数(Function)、还有两个特殊的对象:正则(RegExp)和日期(Date)。面试
从不一样的角度对6种数据类型进行分类: 数组
typeof返回一个表示数据类型的字符串,返回结果包括:number、string、boolean、object、undefined、function。typeof能够对基本类型number、string 、boolean、undefined作出准确的判断(null除外,typeof null===“object”,这是因为历史的缘由,我就不巴拉巴拉了,其实我也说不清楚😢);而对于引用类型,除了function以外返回的都是object。但当咱们须要知道某个对象的具体类型时,typeof就显得有些力不从心了。 bash
typeof 1; // number 有效
typeof ‘ ’;//string 有效
typeof true; //boolean 有效
typeof undefined; //undefined 有效
typeof null; //object 无效
typeof new Function(); // function 有效
typeof [] ; //object 无效
typeof new Date(); //object 无效
typeof new RegExp(); //object 无效
复制代码
当咱们须要知道某个对象的具体类型时,能够用运算符 instanceof,instanceof操做符判断左操做数对象的原型链上是否有右边这个构造函数的prototype属性,也就是说指定对象是不是某个构造函数的实例,最后返回布尔值。 检测的咱们用一段伪代码来模拟instanceof内部执行过程: 微信
instanceof (A,B) = {
var L = A.__proto__;
var R = B.prototype;
if(L === R) {
//A的内部属性__proto__指向B的原型对象
return true;
}
return false;
}
复制代码
从上述过程能够看出,当 A 的 __proto__ 指向 B 的 prototype 时,就认为A就是B的实例,咱们再来看几个例子:函数
[] instanceof Array; //true
[] instanceof Object; //true
new Date() instanceof Date;//true
new Date() instanceof Object;//true
function Person(){};
new Person() instanceof Person;//true
new Person() instanceof Object;//true
复制代码
咱们发现,虽然 instanceof 可以判断出 [] 是Array的实例,但它认为 [] 也是Object的实例,为何呢? 咱们来分析一下[]、Array、Object 三者之间的关系: 从instanceof 可以判断出 [].__proto__ 指向 Array.prototype, 而 Array.prototype.__proto__ 又指向了Object.prototype,Object.prototype.__proto__ 指向了null,标志着原型链的结束。所以,[]、Array、Object就造成了以下图所示的一条原型链: ui
从原型链能够看出,[] 的 __proto__ 直接指向Array.prototype, 间接指向Object.prototype, 因此按照 instanceof 的判断规则,[] 就是Object的实例。this
注意:instanceof运算符只能用于对象,不适用原始类型的值。spa
'hello' instanceof String // false
null instanceof Object // false
undefined instanceof Object // false
复制代码
字符串、null和undefined不是对象,因此返回false。 prototype
constructor属性的做用是,能够得知某个实例对象,究竟是哪个构造函数产生的。
var f = new F();
f.constructor === F;// true
复制代码
可是 constructor 属性易变,不可信赖,这个主要体如今自定义对象上,当开发者重写prototype后,原有的constructor会丢失。
function F() {}
F.prototype = {
_name: 'Eric',
};
var f = new F();
f.constructor === F; // false
复制代码
所以,为了规范,在重写对象原型时通常都须要从新给constructor赋值,以保证明例对象的类型不被改写。
function F() {}
F.prototype = {
constructor: F,
_name: 'Eric',
};
var f = new F();
f.constructor === F; // true
复制代码
toString是Object原型对象上的一个方法,该方法默认返回其调用者的具体类型,更严格的讲,是 toString运行时this指向的对象类型, 返回的类型格式为[object,xxx],xxx是具体的数据类型,其中包括:String,Number,Boolean,Undefined,Null,Function,Date,Array,RegExp,Error,HTMLDocument,... 基本上全部对象的类型均可以经过这个方法获取到。
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object Window]
复制代码
须要注意的是,必须经过Object.prototype.toString.call来获取,而不能直接 new Date().toString(), 从原型链的角度讲,全部对象的原型链最终都指向了Object, 按照JS变量查找规则,其余对象应该也能够直接访问到Object的toString方法,而事实上,大部分的对象都实现了自身的toString方法,这样就可能会致使Object的toString被终止查找,所以要用call来强制执行Object的toString方法。
typeof能够准确地判断出基本类型,可是对于引用类型除function以外返回的都是object;
已知是引用类型的状况能够选用instanceof或constructor方法进行具体类型的判断:
instanceof是基于原型链的;
constructor 属性易变,不可信赖,为了规范,在重写对象原型时通常都须要从新给constructor赋值,以保证明例对象的类型不被改写;
Object.prototype.toString.call() 通用但很繁琐。
感谢您花时间读到这里~
按照惯例,推广一下微信公众号“前端麻辣烫”,主要是分享前端知识,着重前端笔试面试知识。欢迎关注~欢迎投稿~
微信搜索微信号:WebSnacks, 或者微信扫码关注哦!