zoukankan      html  css  js  c++  java
  • 判断js数据类型的四种方法,以及各自的优缺点(转)

    转载地址:https://blog.csdn.net/lhjuejiang/article/details/79623973

    数据类型分为基本类型和引用类型:

    基本类型:String、Number、Boolean、Null、Undefined、symbol(ES6)

    引用类型:Object、Array、Date、Function、Error、RegExp、Math、Number、String、Boolean、Globle。

    js内置类型有七种:String、Number、Boolean、Null、Undefined、Symbol(ES6)、Object

    判断数据类型的方法一般可以通过:typeof、instanceof、constructor、Object.prototype.toString.call();四种常用方法

    1、typeof:(可以对基本类型(包括function)做出准确的判断,但对于引用类型,用它就有点力不从心了)

    typeof 返回一个表示数据类型的字符串,返回结果包括:number、boolean、string、object、undefined、function、Symbol6种数据类型。

    对于引用类型,返回的都是object,其实返回object也没有错,因为所有对象的原型链最终都指向了Object,Object是所有对象的`祖宗`。 但当我们需要知道某个对象的具体类型时,typeof 就显得有些力不从心了。

    注意:typeof null也是返回object

    2、instanceof

    判断对象和构造函数在原型链上是否有关系,如果有关系,返回真,否则返回假

    function Aaa(){
    }
    var a1 = new Aaa();
    console.log( a1 instanceof Aaa);  //true判断a1和Aaa是否在同一个原型链上,是的话返回真,否则返回假
    var arr = [];
    console.log( arr instanceof Aaa);//false

    我们来看一下

        var str = 'hello';
        alert(str instanceof String);//false
        var bool = true;
        alert(bool instanceof Boolean);//false
        var num = 123;
        alert(num instanceof Number);//false
        var nul = null;
        alert(nul instanceof Object);//false
        var und = undefined;
        alert(und instanceof Object);//false
        var oDate = new Date();
        alert(oDate instanceof Date);//true
        var json = {};
        alert(json instanceof Object);//true
        var arr = [];
        alert(arr instanceof Array);//true
        var reg = /a/;
        alert(reg instanceof RegExp);//true
        var fun = function(){};
        alert(fun instanceof Function);//true
        var error = new Error();
        alert(error instanceof Error);//true

    从上面的运行结果我们可以看到,基本数据类型是没有检测出他们的类型,但是我们使用下面的方式创建num、str、boolean,是可以检测出类型的:

    var num = new Number(123);
    var str = new String('abcdef');
    var boolean = new Boolean(true);
    console.log(num instanceof Number)
    console.log(num instanceof String)

    3、constructor:查看对象对应的构造函数

    constructor 在其对应对象的原型下面,是自动生成的。当我们写一个构造函数的时候,程序会自动添加:构造函数名.prototype.constructor = 构造函数名

    function Aaa(){
    }
    //Aaa.prototype.constructor = Aaa;   //每一个函数都会有的,都是自动生成的
     
    //Aaa.prototype.constructor = Aaa;

    判断数据类型的方法

        var str = 'hello';
        alert(str.constructor == String);//true
        var bool = true;
        alert(bool.constructor == Boolean);//true
        var num = 123;
        alert(num.constructor ==Number);//true
       // var nul = null;
       // alert(nul.constructor == Object);//报错
        //var und = undefined;
        //alert(und.constructor == Object);//报错
        var oDate = new Date();
        alert(oDate.constructor == Date);//true
        var json = {};
        alert(json.constructor == Object);//true
        var arr = [];
        alert(arr.constructor == Array);//true
        var reg = /a/;
        alert(reg.constructor == RegExp);//true
        var fun = function(){};
        alert(fun.constructor ==Function);//true
        var error = new Error();
        alert(error.constructor == Error);//true

    从上面的测试中我们可以看到,undefined和null是不能够判断出类型的,并且会报错。因为null和undefined是无效的对象,因此是不会有constructor存在的
    同时我们也需要注意到的是:使用constructor是不保险的,因为constructor属性是可以被修改的,会导致检测出的结果不正确

    function Aaa(){
    }
    Aaa.prototype.constructor = Aaa;//程序可以自动添加,当我们写个构造函数的时候,程序会自动添加这句代码
    function BBB(){}
    Aaa.prototype.constructor = BBB;//此时我们就修改了Aaa构造函数的指向问题
    alert(Aaa.construtor==Aaa);//false

    可以看出,constructor并没有正确检测出正确的构造函数

    备注:使用Object.create()创建的js对象,没有constructor

    4、Object.prototype.toString(可以说不管是什么类型,它都可以立即判断出)

    toString是Object原型对象上的一个方法,该方法默认返回其调用者的具体类型,更严格的讲,是 toString运行时this指向的对象类型, 返回的类型

    格式为[object xxx],xxx是具体的数据类型,其中包括:

    String,Number,Boolean,Undefined,Null,Function,Date,Array,RegExp,Error,HTMLDocument,... 基本上所有对象的类型都可以通过这个方法获取到。 

        var str = 'hello';
        console.log(Object.prototype.toString.call(str));//[object String]
        var bool = true;
        console.log(Object.prototype.toString.call(bool))//[object Boolean]
        var num = 123;
        console.log(Object.prototype.toString.call(num));//[object Number]
        var nul = null;
        console.log(Object.prototype.toString.call(nul));//[object Null]
        var und = undefined;
        console.log(Object.prototype.toString.call(und));//[object Undefined]
        var oDate = new Date();
        console.log(Object.prototype.toString.call(oDate));//[object Date]
        var json = {};
        console.log(Object.prototype.toString.call(json));//[object Object]
        var arr = [];
        console.log(Object.prototype.toString.call(arr));//[object Array]
        var reg = /a/;
        console.log(Object.prototype.toString.call(reg));//[object RegExp]
        var fun = function(){};
        console.log(Object.prototype.toString.call(fun));//[object Function]
        var error = new Error();
        console.log(Object.prototype.toString.call(error));//[object Error]

    从这个结果也可以看出,不管是什么类型的,Object.prototype.toString.call();都可以判断出其具体的类型。
    接下来我们分析一下四种方法各自的优缺点
    不同类型   typeof                                instanceof                                                    constructor                                                                            Object.prototype.toString.call

    的优缺点

    优点 使用简单                                      能检测出引用类型                                      基本能检测所有的类型(除了null和undefined)                      检测出所有的类型
    缺点 只能检测出基本类型(出null)  不能检测出基本类型,且不能跨iframe               constructor易被修改,也不能跨iframe IE6下,undefined和null均为Object

    从上表中我们看到了,instanceof和constructor不能跨iframe,上面没有细说,所以下面我们直接上例子喽

    例:跨页面判断是否是数组

    window.onload = function(){
        
        var oF = document.createElement('iframe');
        document.body.appendChild( oF );
        
        var ifArray = window.frames[0].Array;
        
        var arr = new ifArray();
        
        //alert( arr.constructor == Array );  //false
        
        //alert( arr instanceof Array );  //false
        
        alert( Object.prototype.toString.call(arr) == '[object Array]' );  //true
        
        
    };

    从结果中可以看出,constructor和instanceof都没有正确的判断出类型,只有object.prototype.toString.call();正确判断出了

    其实面试官也经常喜欢让说一种最简单的判断是数组的方法,记住喽是object.prototype.toString.call()哦!

  • 相关阅读:
    HelloDjango 第 02 篇:"空空如也"的博客应用
    HelloDjango 第 01 篇:开始进入 django 之旅
    HelloDjango 启动!免费带你学Django全栈!
    抛却纷争,百度给开源世界带来了什么?
    SQL Server Cast、Convert数据类型转换
    Json动态添加属性
    模式的秘密-观察者模式(四)
    模式的秘密-观察者模式(三)
    模式的秘密-观察者模式(二)
    模式的秘密-观察者模式(一)
  • 原文地址:https://www.cnblogs.com/zhaobao1830/p/10126813.html
Copyright © 2011-2022 走看看