• JS判断对象类型


    今天来讲讲如何判断 JS 的变量类型。

    JS 真不愧是坑爹的语言。

    先来个悬念~看完你就懂!!!

    const a = new String('aa');
    const b = 'aa';
    console.log(a instanceof String); // true
    console.log(b instanceof String); // flase
    
    • typeof - 最基本的,有六种返回值,用法 typeof xx/typeof(xx).

    检测引用类型值的时候,它的作用不大。

    • instanceof - variable instanceof Object
    • constructor - 写在纸上的发源地,可以被强行篡改。
    • Object.prototype.toString.call(element) - 无法被篡改的祖先,血液里DNA.

    一. typeof

    主要用于区分基本数据类型和对象。

    使用方法: typeof(variable)/typeof variable
    使用结果(6种):

    • number
    • boolean
    • string
    • undefined
    • function
    • object

    使用示例:

    const a = 3;        // number
    const b = 'haha';   // string
    const c = true;     // boolean
    const d = null;     // object
    const e = undefined;// undefined
    const f = function() {}   // function
    

    总的来说,typeof对于 数组,RegExp(正则),Date等是无力的。


    让我们来看一下有一起 JS机制 造成的惊天悬疑案???难道 'aa'和'aa'之间还有种族差别??神秘种族! 基本包装类型!=基本数据类型

    实际上还有一种类型叫做:基本包装类型

    [基本包装类型有:Number/String/Boolean]

    const a = new String('aa');    // object
    const b = new Number(3);       // object
    const c = new Boolean(true);   // object
    const a = 'haha';   // string
    const b = 3;        // number
    const c = true;     // boolean
    

    实际上呢,这也是基本类型能够拥有方法的原因。短暂蜕变成为基本包装类型 拥有方法 -> 超级赛亚人短暂地获得他们本来没有的实力???哈哈哈

    let s1 = 'haha';         // haha
    let s2 = s1.substring(2);// ha
    

    在程序中,其实他们的运行过是这个样子的!

    let s1 = new String('haha');
    let s2 = s1.substring(2);
    s1 = null;
    
    • a.创建 String 类型的一个实例
    • b.在实例上调用指定的方法
    • c.销毁这个实例

    经过上面的处理, 基本的字符串类型就变得 和 对象一样了

    引用类型和基本包装类型的区别在于对象的生存期。自动创建的基本包装类型实际上只存在于运行的一瞬间。

    因为只有一瞬间,所以实际上他们还不是对象,没有办法被添加属性和方法

    let s1 = 'some text';
    s1.color = 'red';
    console.log(s1.color); // undefined
    

    二. instanceof

    它主要用于区分 引用类型。

    专业解释: instanceof运算符用来判断一个构造函数的prototype属性所指向的对象是否存在另外一个要检测对象的原型链上

    const a = new String('aa');
    const b = 'aa';
    console.log(a instanceof String); // true
    console.log(b instanceof String); // flase
    

    上面这个就是我们开头的 悬念了,实际上,看了上面 typeof 相关的解释,这里你是不是也知道了呢!基本包装类型(引用类型)和基本数据类型的差别

    使用方法: obj instanceof Object

    普通实例(找到他们的父类):

    function Person(){};
    function Coder(){};
    var p = new Person();
    var s = new Coder();
    console.log(p instanceof Person); // true
    console.log(s instanceof Coder); // true
    

    这里是它的一些缺陷的证据(新手跳过)

    文艺实例: (这里可以先跳过,看完 高程三 再回来看比较好,比较难)

    function Person() {}
    console.log(Object instanceof Object);     // true
    
    // 第一个Object的原型链:Object => Object.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype
    // 第二个Object的原型:  Object => Object.prototype
    
    console.log(Function instanceof Function); // true
    
    // 第一个Function的原型链:Function => Function.__proto__ => Function.prototype
    / /第二个Function的原型:Function => Function.prototype
    
    console.log(Function instanceof Object);   // true
    
    // Function => Function.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype
    // Object => Object.prototype
    
    console.log(Person instanceof Function);      //true
    
    // Person => Person.__proto__ => Function.prototype
    // Function => Function.prototype
    
    console.log(String instanceof String);   // false
    // String => String.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype
    // String的原型链:String => String.prototype
    
    console.log(Boolean instanceof Boolean); // false
    // Boolean => Boolean.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype
    // Boolean=>Boolean.prototype
    
    console.log(Person instanceof Person); // false
    // Person => Person.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype
    // Person=>Person.prototype
    

    本意是用来判断 A 是否是 B 的实例对象。这里需要注意。instanceof 检测的是原型。

    我们很容易发现问题(通过基本包装类型)。它能够检测出 [] 是 Array 的实例,却不能检测出 [] 不是 Object 的实例。

    [] instanceof Array // true
    [] instanceof Object // true 不应该啊兄弟
    
    var a = new Number(1);
    var b = 1;
    a instanceof Number; // true
    b instanceof Number; // false 不应啊兄弟
    

    因此,我们用 instanceof 也不能完全精确的判断object类的具体数据类型。
    同时,我们发现,使用 Object.prototype.toString.call(x) 时,以上结果都符合预期。

    三. constructor

    JavaScript中,所有对象都有一个 constructor 属性,它引用初始这个对象的构造函数

    constructor就像是写在 纸上 的种族,只要是在纸上的东西,都可能是可以改的,所以,它并不稳定。

    constructor 是个属性,在 JS 中,大多数属性是可以被修改的。

    // 以下代码运行于 Node v10 环境下
    var a = [1, 2];
    var b = new Array(3);
    var c = 'test';
    var d = new String('test');
    
    console.log(d.constructor === String); // true
    console.log(c.constructor === String); // true
    console.log(b.constructor === Array);  // true
    console.log(a.constructor === Array);  // true
    

    也许你会觉得无厘头?谁会这么改,但是:人们有这么做的可能性,我们就应该防范。

    var d = new String('test');
    String.prototype.constructor = "I'm change.";
    console.log(d.constructor); // I'm change
    console.log(d.constructor === String); // false
    

    四. 无敌的判断者: Object.prototype.toString.call(element) - 这是源头的源头。

    constructor好比我们人类的发源地,比如 亚洲。而这个呢,相当于是地球。

    它和下者的差距在这里: https://www.zhihu.com/question/50934612

    var d = new String('test');
    console.log(Object.prototype.toString.call(d)); // [object String]
    var b = new Array(3);
    console.log(Object.prototype.toString.call(b)); // [object Array]
    

    complete.

  • 相关阅读:
    Codeforces Round #719 (Div. 3) 题解
    Codeforces Global Round 14 A~F题解
    AtCoder Beginner Contest 199 题解
    Codeforces Round #716 (Div. 2) A~D 题解
    Codeforces Round #713 (Div. 3) 题解
    Codeforces Round #712 (Div. 2) A~E 题解
    CodeCraft-21 and Codeforces Round #711 (Div. 2) A~E 题解
    CF839 D 莫比乌斯反演
    java存大数和高精度浮点数(BigInteger与BigDecimal)
    java科学计算常用方法(Math)
  • 原文地址:https://www.cnblogs.com/can-i-do/p/7149159.html
Copyright © 2020-2023  润新知