JS数据类型的分类和判断

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> JS数据类型的分类和判断

    

点击上方蓝色字体,关注我们

15

在前端笔试面试中“JS数据类型的分类和判断”是高频的基础考点,今天总结一下,对正在准备找工作的小伙伴应该有所帮助~

JavaScript中有6种数据类型:数字(number)、字符串(string)、布尔值(boolean)、undefined、null、对象(Object)。其中对象类型包括:数组(Array)、函数(Function)、还有两个特殊的对象:正则(RegExp)和日期(Date)。

分类


  从不同的角度对6种数据类型进行分类:
JS数据类型的分类和判断

判断


对变量数据类型的判断通常有4种方法:

** **typeof返回一个表示数据类型的字符串,返回结果包括:number、string、boolean、object、undefined、function。typeof可以对基本类型number、string  、boolean、undefined做出准确的判断(null除外,typeof null===“object”,这是由于历史的原因,我就不巴拉巴拉了,其实我也说不清楚😢);而对于引用类型,除了function之外返回的都是object。但当我们需要知道某个对象的具体类型时,typeof就显得有些力不从心了。


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就形成了如下图所示的一条原型链:

JS数据类型的分类和判断

从原型链可以看出,[] 的 proto  直接指向Array.prototype, 间接指向Object.prototype, 所以按照 instanceof 的判断规则,[] 就是Object的实例。

注意,instanceof运算符只能用于对象类型,不适用基本类型的值。


'hello' instanceof String // false
null instanceof Object // false
undefined instanceof Object // false

字符串、null和undefined不是对象类型,所以返回false。


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来获取。

总结


typeof可以准确地判断出基本类型,但是对于引用类型除function之外返回的都是object;

已知是引用类型的情况可以选用instanceof或constructor方法进行具体类型的判断:

instanceof是基于原型链的;

constructor 属性易变,不可信赖,为了规范,在重写对象原型时一般都需要重新给constructor赋值,以保证实例对象的类型不被改写;

Object.prototype.toString.call() 通用但很繁琐。

15

始发于微信公众号: 前端麻辣烫

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> JS数据类型的分类和判断


 上一篇
JS笔试题(7)同步与异步 JS笔试题(7)同步与异步
题目  for (var i = 0; i 5; i++) {     setTimeout(function() {         console.log( i);     }, 1000); } console.log(
2021-04-05
下一篇 
回流重绘 回流重绘
前端面试中“页面的回流与重绘”是性能优化方面经常考察的一个知识点。今天总结一下,有不对或者不全面的地方欢迎指正~ 1 在讨论页面重绘、回流之前,需要对页面的呈现流程有些了解,页面是怎么把HTML结合CSS等显示到浏览器上的,下面的流程图显示
2021-04-05