• JavaScript变量类型检测总结


    JavaScript中的变量类型:

    基本类型Undefined,Null,Boolean,NumberString.

    按值访问(可直接操作保存在变量中的变量值);

    复制规则:当复制基本类型值时:两个变量完全独立,不会互相影响。如下所示:

    var a = b = 1;
    var c = a;
    b = 2;
    c = 3;
    console.log(a); //1
    console.log(b); //2
    console.log(c); //3

    引用类型值包含多个值的对象,是一种将数据(属性)与功能(方法)组织在一起的数据结构。

    按引用访问(不能直接操作对象的内存空间,操作的实际上是对象的引用);

    复制规则:当复制引用类型的值时,复制的其实是一个指针,该指针指向堆中的同一个对象;所以原变量和复制的变量实际上将引用同一个对象,即改变其中一个,另一个也会跟着变化。如下所示:

    var cat = new Object();
    var dog = cat;
    dog.name = "tom";
    console.log(cat.name); //tom

    变量类型检测:

    方法一:type of

    有两种写法typeof xxx ,typeof(xxx)

    typeof 2 //   number
    typeof null //   object
    typeof undefined //  undefined
    typeof '123' //    string
    typeof true //     boolean
    
    typeof {} //   object
    typeof [] //   object
    typeof (function(){}) //  function
    typeof new Object() //object
    typeof Object //function
    typeof /[hbc]at/gi //object

    可以看到,用type of 可以很好的区分出number,undefined,string,boolean这四种基本数据类型,但null会被判定为object.此外,该方法还能检测出函数和对象,但是并不能知道某个对象具体是什么类型的实例。

    方法二:constructor

    每一个对象实例都可以通过 constructor 属性访问它的构造函数:

    var cat = new Cat();
    console.log(cat.constructor === Cat) //  true
    console.log(cat.constructor === Cat.prototype.constructor) //  true

    其实这里的constructor属性并不是实例本身的,而是实例在其原型链上找到的属性,即cat.__proto__对象的属性,而由原型规则(我的另一篇博客写了原型规则)我们知道,cat.__proto__.constructor === Cat,所以继承到该属性后,cat.constructor === Cat

    参考文献:https://blog.csdn.net/zengyonglan/article/details/53465505

    方法三:instanceof

    一般用法:如果被检测变量是给定类型的实例,则返回true。

    var strObj = new String(); 
    strObj instanceof String //true
    strObj  instanceof Object //true

    如图所示,strObj是String类型的实例,故返回true,另外,由于所有对象都是Object类型的实例,故第三行也返回true。

    但其实该方法并没有这么简单,首先说明一点:JS中实例对象的隐式原型.__proto__ === 其构造函数的显式原型.prototype;该方法就是检测左侧的__proto__原型链上,是否存在右侧的prototype原型;即L.__proto__.__proto__ ..... === R.prototype ?如果存在返回true 否则返回false。所以所有的实例 instanseof Object 都返回true ,比如上述代码第三行,然而实例strObj并不是Object直接new出来的实例。那么怎么判断出该实例是否是某构造函数直接new出来的实例呢?可以结合上述constructor属性:

    strObj.__proto__.constructor === String; //true
    
    strObj.__proto__.constructor === Object; //false

    便可以准确的判断出strObj的直接和构造函数是String而非Object了。

     

    关于instanceof和原型链的原理下面两篇文章说的比较清楚:

    https://www.cnblogs.com/libin-1/p/5820550.html

    https://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/

    这种方法较为稳妥,却不能具体的检测出某个变量的具体类型。那有没有一种方法可以准确的检测出某个变量的类型呢?方法4便是:

    方法四:Object.prototype.toString.call()

    1.判断基本类型:

    Object.prototype.toString.call(null);//”[object Null]”
    Object.prototype.toString.call(undefined);//”[object Undefined]”
    Object.prototype.toString.call("abdaw");//”[object String]”
    Object.prototype.toString.call(1);//”[object Number]”
    Object.prototype.toString.call(true);//”[object Boolean]”

    2.判断原生引用类型:

    //函数类型:
    var foo = Function()
    console.log(Object.prototype.toString.call(foo))//”[object Function]”
    //日期类型:
    var date = new Date();
    console.log(Object.prototype.toString.call(date))//”[object Date]”
    //数组类型:
    var arr = [1,2,3];
    console.log(Object.prototype.toString.call(arr))//”[object Array]”
    //正则表达式:
    var reg = /[hbc]at/gi;
    console.log(Object.prototype.toString.call(reg))//”[object RegExp]”
    //自定义类型:
    function Cat(name) {
    this.name = name;
    }
    var cat = new Cat("Tom");
    console.log(Object.prototype.toString.call(cat)) //”[object Object]”

    然而这种方法不能准确判断cat是Cat类的实例,这时可以结合instanceof 操作符来进行判断:person instanceof Person //true。

    文章仅代表个人理解,如有错误或补充,欢迎指出。

  • 相关阅读:
    C语言复习---杨辉三角打印
    C语言复习---获取矩阵的对角和
    C语言复习---选择法排序
    C语言复习---用筛选法求100之内的素数
    C语言复习---比赛问题
    C语言复习---打印菱形
    建立一个node.js服务器(使用express搭建第一个Web环境)
    nodejs小问题:express不是内部或外部命令
    使用express搭建第一个Web应用【Node.js初学】
    Node.js 相关资料网站汇总
  • 原文地址:https://www.cnblogs.com/YiNongLee/p/9209982.html
Copyright © 2020-2023  润新知