zoukankan      html  css  js  c++  java
  • 检测数据类型的几种方法

    ECMAscript 中规定的数据类型有:

    1. 简单类型:string、number、boolean、undefined、null、symbol、bigint
    2. 引用(复杂)类型:object
      object 又分为:普通对象 {}、数组对象 []、函数 function(){}

    ============================= 分割线 =============================

    检测这些数据的类型的方法有:

    第一种:typeof 可以检测一些基本的数据类型

    语法:typeof 后面加不加括号都是可以用的

    注意:正则、{}、[]、null 输出结果为 object

    所以这个方法并不是很好

    例子:

    console.log(typeof /\d/); // object
    console.log(typeof {}); // object
    console.log(typeof []); // object
    console.log(typeof (null)); // object
    console.log(typeof 123); // number
    console.log(typeof true); // boolean
    console.log(typeof function () {}); // function
    console.log(typeof (undefined)); // undefined
    console.log(typeof(10n)); // bigint
    

    第二种:valueOf

    可以看到数据最本质内容(原始值)
    例子:

    let x = "12345";
    let s = new String('12345');
    console.log(typeof x); // string
    console.log(typeof s); // object
    console.log(x == s); // true  (typeof检测出来是对象居然和一个数组相等,显然s并不是一个真的对象。)
    // 此时看看 valueOf()的表现
    console.log(s.valueOf()); // 12345  拿到s的原始值是 字符串的12345
    console.log(typeof s.valueOf()) // string  这才是 s 的真正的数据类型
    

    第三种:instanceof 检测当前实例是否隶属于某各类。

    双目运算符 a instanceof b ,判断a的构造器是否为b,返回值为布尔值

    例子:

    function fn() {}
    let f = new fn;
    console.log(f instanceof fn); // true
    console.log(f instanceof Object); // true
    let arr = [1,2,3,4];
    console.log(arr instanceof Array); // true
    

    第四种:constructor 构造函数

    语法:实例.constructor
    对象的原型链下(===构造函数的原型下)有一个属性,叫 constructor
    缺点:constructor 并不可靠,容易被修改(只有参考价值)。即使被修改了,也不会影响代码的正常运行。
    正常开发的时候,constructor 不小心被修改了,为了方便维护,和开发,可以手动更正 constructor 的指向。

    例子:

    function fn() {}
    let f = new fn;
    console.log(f.constructor.name); // fn
    console.log(fn.constructor); // Function(){}
    console.log(Function.constructor); // Function(){}
    

    第五种:hasOwnproperty 检测当前属性是否为对象的私有属性,而不是继承自原型链。

    语法: obj.hasOwnproperty("属性名(K值)")

    例子:

    let obj = {
      name: "xx"
    };
    console.log(obj.hasOwnProperty('name')); // true
    console.log(obj.hasOwnProperty('xxxx')); // false
    

    扩展:
    由于 hasOwnProperty 并非关键字,所以我们很有可能将对象的一个属性命名为 hasOwnProperty,这样一来就无法再使用对象原型的 hasOwnProperty 方法来判断属性是否是来自原型链。

    var foo = {
        hasOwnProperty: function() {
            return false;
        },
        bar: 'Here be dragons'
    };
    foo.hasOwnProperty('bar'); // 始终返回 false
    

    不能使用 该对象.hasOwnProperty 这种方法,怎么来解决这个问题呢?我们需要使用原型链上真正的 hasOwnProperty 方法:

    ({}).hasOwnProperty.call(foo, 'bar'); // true
    // 或者:
    Object.prototype.hasOwnProperty.call(foo, 'bar'); // true
    

    Object.prototype.hasOwnProperty.call(foo, 'bar'):Object.prototype.hasOwnProperty 在 .call 之后,this 指向了对象 foo,并传入参数 'bar',相当于执行了 foo.hasOwnProperty('bar'),不同是的是此时的 hasOwnProperty 是我们想要的方法。

    第六种:isArray 判断是否为数组、 isNaN() 判断是否是NaN

    例子:

    console.log(Array.isArray([])); // true
    console.log(Array.isArray(new Array())); // true
    console.log(isNaN(NaN)) // true
    console.log(isNaN(+"12ab"))  //true
    

    第七种:Object.portotype.toString (最好的)

    语法:Object.prototype.toString.call([value])
    获取 Object.portotype 上的 toString 方法,让方法的 this 变为需要检测的数据类型值,并且让这个方法执行
    在Number、String、Boolean、Array、Function、RegExp...这些类的原型上都有一个toString方法:这个方法就是把本身的值转化为字符串

    (12).toString() // '12'
    (true).toString() // 'true'
    [12,23].toString() // '12.23'
    

    在Object这个类的原型上也有一个方法toString,但是这个方法并不是把值转换成字符串,而是`返回当前值得所属类详细信息,固定结构:'[object 所属的类]'

    var obj = {name: '珠穆朗玛峰'}
    obj.toString() // "[object Object]"
    

    调取的正是 Object.prototype.toString 方法

    obj.toString()
    首先执行 Object.prototype.tostring 方法
    这个方法中的 this 就是我们操作的数据值 obj
    =>总结:Object.prototype.toString 执行的时候返回当前方法中的 this 的所属类信息
    也就是,我想知道谁的所属类信息,我们就把这个toString方法执行,并且让 this 变为我们检测的这个数据值,那么方法返回的结果就是当前检测这个值得所属类信息

    Object.prototype.toString.call(12) // "[boject Number]"
    Object.prototype.toString.call(true) // "[boject Boolean]"
    ({}).toString.call([1, 2]) // "[object Array]"
    /* 
    "[object Number]"
    "[object String]"
    "[object Object]"
    "[object Function]"
    "[object Undefined]"
    "[object Null]"
    "[object RegExp]"
    "[object Boolean]"
    */
    

    使用toString检测数据类型,不管你是啥值,我们都可以正常检测出需要的结果(这个方法检测是万能的)

    话外:

    1.Math是个对象,不是类。类才有prototype(原型)。也就是说类都有原型:prototype,对象都有原型链:proto,函数既是类,也是对象,也是函数。
    2.如何把对象转换成字符串?
     对象下的toString方法是检测数据类型的,而不是用来转化成字符串的,这时可以用JSON的方法来转化

    {name:'朱军林'}.toString() // => "[object Object]"
    
    JSON.stringify({name:'朱军林'}) // => "{'name':'朱军林'}"
    
  • 相关阅读:
    【BUG修复】视频综合管理平台EasyNVS首页设备接入情况显示与实际不符如何调整?
    数据库连接池
    手写SORM(simple object relation mapping)框架3—DBManager和TableContext的设计
    jdbc—总结
    jdbc—CLOB和BLOB
    jdbc—时间处理
    jdbc—事务
    递归(最大公约数)
    C++ return
    函数参数
  • 原文地址:https://www.cnblogs.com/MrZhujl/p/9837152.html
Copyright © 2011-2022 走看看