• JS获取对象数据类型的方法



    1.typeof:  语法:typeof 对象 或者 typeof(对象)
       返回对象的数据类型:只有原始数据类型:boolean number string undefined function object

    由于最初的BUG导致null的数据类型成为了object,现在,null 被认为是对象的占位符,从而解释了这一矛盾。
    缺陷:对于Array,null,Object对象和其他自定义对象使用typeof一律返回object;

    console.log(typeof(x)); //未声明x,返回undefined
        var y = false;
        console.log(typeof y);  //boolean
        var str = "字符串";
        console.log(typeof str);    //string
        var num = 5;
        console.log(typeof(num));   //number
        console.log(typeof NaN);    //number    NaN是一个特殊的数字---非数字
        var f1 = function () {
    
        };
        console.log(typeof f1); //function
    
        console.log(typeof null);   //object
        var arr = [1, 2, 3];
        console.log(typeof arr);    //object
        var obj = {name: "小伟", age: 15};
        console.log(typeof obj);    //object
        var Person = function (name) {
            this.name = name
        };
        var per = new Person("小王");
        console.log(typeof per);    //object
     2.instanceof  用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置
             解读:用于判断某个对象是不是某个构造函数的一个实例,或者是不是某个构造函数的一个后代实例
            语法:对象 instanceof 数据类型(或者构造函数名):返回true/false
      
    instanceof的原理:function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
    var O = R.prototype;// 取 R 的显示原型
    L = L.__proto__;// 取 L 的隐式原型
    while (true) {
    if (L === null)
    return false;
    if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true
    return true;
    L = L.__proto__;
    }
    }
    即比较对象.__proto__和数据类型(构造函数).prototype,如果相等就为true,
    不同就继续跟着对象的原型链,比较对象隐式原型里的隐式原型与数据类型(构造函数).prototype
    根据原型链的知识直到原型链的最终,指向Object.prototype.__proto__---为null
     console.log(per instanceof Person);     //true
        //per.__proto__指向其构造函数的原型对象Person.prototype,所以返回true
    
        console.log(f1 instanceof Function);    //true
        console.log(arr instanceof Array);  //true
        console.log(obj instanceof Object);  //true
        //同理,这些引用类型:Function、Array、Object、都可以视为一个构造函数
    
        //对于继承的数据类型:新的实例对象根据原型链,数据类型可以是其构造函数名,也可以是其祖辈的构造函数名
        var Student = function (score) {
            this.score = score;
        }
    
        Student.prototype = new Person("小李");
        var stu = new Student(100);
    
        console.log(stu instanceof Student);    //true  stu.__proto__ == Student.prototype很易理解
        console.log(stu instanceof Person);     //true
        /*
        * 根据原型链:stu.__proto__ == Student.prototype == new Person
        *           stu.__proto__.__proto__ == new Person.__proto__ == Person.prototype
        *
        *
        * */

    注意:

     * 在JavaScript中,一切都是一个对象( 或者至少被视为一个对象) 。
    * 唯一的non-objects是基本类型:布尔值,数字,字符串和undefined ,
    * 直接声明的这几种类型的实例不是object对象,但是可以访问其作为对象的一些属性和方法?为什么呢?
    *
    * 在访问基本类型数据的属性和方法时会临时出现一个包装对象:
    * 自动创建基本包装类型的对象,只执行一行代码的瞬间之后就会立即销毁。
         这意味着在运行时为基本包装类型值添加属性和方法是无效的。
    * 比如只要引用了字符串s的属性,JavaScript就会将字符串值通过调用new String(s)的方式转换成对象,成为了基本包装类型,
    * 这个对象继承了字符串(String)对象的方法,并被用来处理属性的引用。一旦属性引用结束,这个新创建的对象就会被销毁
    *
    * instanceof 运算符只对对象有效:所以对于上述的几个non-object无效,所以判断他们的数据类型时返回值会是false
    *
    * 另外:布尔,数字,字符串有其构造函数,如果用其构造函数实例化一个对象,则可以使用instanceof判断其数据类型
    *
     var y = false;
        console.dir(y); //只是一个基本布尔值,没有内部结构
        console.log(y instanceof Boolean);  //false
    
        var z = new Boolean(false);
        console.dir(z); //利用构造函数创建布尔值,可以得到内部结构,具有对象的特征
        console.log(z instanceof Boolean);  //true
    
        console.log(y.__proto__);   //由于基本包装类型的存在,可以临时访问其作为对象的属性,
        // 这样做时,会将y通过调用new Boolean得到一个临时的包装对象,具有对象特征,但是语句执行结束后就消失
        y.name = "布尔false";
        console.log(y.name);    //undefined,无法对基本类型添加属性或方法
        //无法对基元类型的数据声明属性和方法,因为他们不是对象,
        // 可以利用包装类型的原理访问基元类型数据的属性和方法(如果他们所对应的包装对象有这个属性和方法的话,如果没有,返回undefined很容易理解)
    
    
        console.log(str instanceof String); //false
        console.log(num instanceof Number); //false
     3.借用Object原型里的一个方法 :Object.prototype.toString.call(对象)
    可以得到对象的数据类型:包括:String、Number、Boolean、undefined、null、Object、function、Array、Date、Regexp
    解决了typeof的缺陷
    但是无法得到自定义构造函数实例化对象的数据类型(构造函数名),只能获得Object

    注意:使用这个方法实际上是用call()方法借用Object原型里的一个方法,不能直接使用对象.toString(),
    因为对于一个对象,toString方法是被重新定义了的,是将obj转换为字符串的方法,
    直接使用对象.toString()根据原型链,在访问到这个重写的方法时就调用了,不能访问到Object原型里的这个同名的方法
    console.log(Object.prototype.toString.call(null));//[object Null]
        console.log(Object.prototype.toString.call(undefined)); //[object Undefined]
        console.log(Object.prototype.toString.call(y)); //[object Boolean]
        console.log(Object.prototype.toString.call(str));//[object String]
        console.log(Object.prototype.toString.call(num));//[object Number]
        console.log(Object.prototype.toString.call(f1));//[object Function]
        console.log(Object.prototype.toString.call(arr));//[object Array]
        console.log(Object.prototype.toString.call(obj));//[object Object]
        console.log(Object.prototype.toString.call(per));//[object Object]
        console.log(Object.prototype.toString.call(new Date));//[object Date]


  • 相关阅读:
    得不到的永远在骚动
    这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧【转】
    Windows CMD命令大全【转】
    创业为什么选择北上广?
    为什么你还把时间浪费在无效人脉社交上?
    五步搞定Android开发环境部署——非常详细的Android开发环境搭建教程
    mysql分区操作
    程序员常用网站
    4种提升SQL查询性能的知识
    获得局域网内其他成员的信息
  • 原文地址:https://www.cnblogs.com/yucheng6/p/9747313.html
Copyright © 2020-2023  润新知