如何精确判断JavaScript中任意变量的具体数据类型?

2026-04-03 06:531阅读0评论SEO教程
  • 内容介绍
  • 相关推荐

本文共计1782个文字,预计阅读时间需要8分钟。

如何精确判断JavaScript中任意变量的具体数据类型?

目录- 判断类型常用的方法 - typeof - instanceof - toString - 封装一个获取类型的函数 - typeof - instanceof - toString- 总结 - JS是弱类型语言,或者说动态语言 - 在定义变量时,我们不需要提前声明类型

如何精确判断JavaScript中任意变量的具体数据类型?

目录
  • 判断类型常用的方法
    • typeof
    • instanceof
    • toString
  • 封装一个获取类型的函数
    • typeof + instanceof(不推荐)
    • toString
  • 总结

    js是弱类型语言,或者说是动态语言,在定义变量时我们可以不提前声明变量的类型,也可以在变量声明后赋予不同类型的值。变量的类型会在程序运行的过程中被确定。对于开发者来说,虽然可以不用频繁的定义不同的数据类型,但是如果是比较复杂的项目,或者接手他人的项目,发现一个变量到处被使用并且赋予不同类型的值,也许头都大了。变量类型的不确定还可能出现运行时报错:xxx is not a function,根本原因就是不同的数据类型所具有的方法是不一样的,也许有的大家都有,因此不报错;但是如果是特有的,或者有差异的,不判断变量的类型就直接调用,就有可能出现生产bug。那么应该如何才能获取准确的变量类型呢?

    判断类型常用的方法

    typeof

    js内置的一个运算符,返回一个字符串,表示操作数的类型。可用于number、string、boolean等值类型,function函数,object等引用类型,如果是判断对象类型,则只能得到object,无法得到具体的值。

    console.log(typeof ''); // string console.log(typeof (() => {})); // function console.log(typeof Symbol()); // symbol console.log(typeof undefined); // undefined console.log(typeof null); // object console.log(typeof []); // object console.log(typeof {}); // object

    我们可以看到,数组、对象通过typeof都是返回了object,无法细分;其中值得注意的是typeof null结果也是object。这是因为在js的最初实现中,js中的值是由一个表示类型的标签以及实际数据值组合表示的。对象类型的标签是0,我们都知道null表示空,在大多数平台下其值为0x00,因此对象和null的类型标签是一样的。类型标签一样,但是null却没有正常对象的属性以及方法。

    instanceof

    instanceof也是js内置的一个运算符,用于判断两个参数之间是否存在联系,实现原理是检测构造函数的prototype属性是否出现在某个实例对象的原型链上。如果是,则返回true;否则,返回false。

    console.log({} instanceof Array); // false console.log([] instanceof Array); // true console.log({} instanceof Object); // true console.log([] instanceof Object); // true

    instanceof是判断两个参数,并不会直接获取变量的类型,可以通过枚举的方式简介获取。

    toString

    每一个对象都有一个toString()方法,因为每个对象都会继承自Object。可能在大多数人的印象中,toString()只是用来返回一个字符串,并没有什么特别的地方,那是因为你看到的toString()基本上都是被重写后的,原始的toString()是可以用来获取对象的类型的。

    举个例子:

    const o = new Object(); o.toString(); // [object Object] const arr = [1,2,3]; // 数组也会继承自Object arr.toString(); // '1,2,3',因为数组重写了toString

    每个对象都能通过Object.prototype.toString.call(thisArg)或者Object.prototype.toString.apply(thisArg)来获取其类型:

    console.log(Object.prototype.toString.call(null)); // [object Null] console.log(Object.prototype.toString.call(undefined)); // [object Undefined] console.log(Object.prototype.toString.call([])); // [object Array] console.log(Object.prototype.toString.call({})); // [object Object] console.log(Object.prototype.toString.call(() => {})); // [object Function]

    每次都调用js内置的API还是有点麻烦,所以我们还是封装一个函数getType

    封装一个获取类型的函数

    typeof + instanceof(不推荐)

    之前我们也提到了typeof可以获取部分数据类型,instanceof可以用枚举来表示剩下的类型,那么这两者结合是不是就可以实现getType了呢?

    function getType(obj) { if (typeof obj === 'object') { if (obj instanceof Array) return 'array'; if (obj instanceof Map) return 'map'; if (obj instanceof Set) return 'set'; if (obj instanceof RegExp) return 'regexp'; // 尽可能枚举类型,最后兜底返回object return 'object' } return (typeof obj); } console.log(getType(null)); // object console.log(getType(undefined)); // undefined console.log(getType('')); // string console.log(getType([])); // array console.log(getType(/a/)); // regexp console.log(getType(new WeakMap())); // object console.log(getType(new WeakSet())); // object

    使用此方式虽然可以实现getType,但是存在弊端;

    • 由于是枚举,导致代码长度可能会很长
    • 枚举的数据类型可能有限,未能覆盖常用数据类型
    • 如果要新增类型,则需要修改代码

    关于toString()的用法刚刚已经说了,我们以此来实现一个getType

    function getType(obj) { const originType = Object.prototype.toString.call(obj); // 获取类型。返回格式为[object type],需要提取出type的值 const firstSpaceIndex = originType.indexOf(' '); // 找到第一个空格所在下标 const type = originType.slice(firstSpaceIndex + 1, -1); // 跳过空格,截取到倒数第一个字符(不含最后一个) return type.toLowerCase(); // 转换为小写 } console.log(getType(null)); // null console.log(getType(undefined)); // undefined console.log(getType('')); // string console.log(getType([])); // array console.log(getType(/a/)); // regexp console.log(getType(new WeakMap())); // weakmap console.log(getType(new WeakSet())); // weakset

    实现getType我们也可以借助于操作数组的方式:

    function getType(obj) { const originType = Object.prototype.toString.call(obj); // 获取类型。返回格式为[object type],需要提取出type的值 const tmpType = originType.split(' ')[1]; // 根据空格分割,并取第二个 const type = tmpType.slice(0, -1); // 从0截取到倒数第一个字符(不含最后一个) return type.toLowerCase(); // 转换为小写 } console.log(getType(null)); // null console.log(getType(undefined)); // undefined console.log(getType('')); // string console.log(getType([])); // array console.log(getType(/a/)); // regexp console.log(getType(new WeakMap())); // weakmap console.log(getType(new WeakSet())); // weakset

    两者实现结果是一致的,基本上实现了我们的既定目标,而且可以获取到所有的数据类型。不同的是,操作数组比直接操作字符串更消耗性能。

    总结

    实现一个获取变量类型的方法,其实并不复杂,简单来说就是使用了内置的API:Object.prototype.toString()。有时候,往往就是因为过于简单而被我们忽略,其实越是简单的方式,才是越有效的。

    以上就是详解JavaScript如何准确获取任意变量的数据类型的详细内容,更多关于JavaScript获取变量数据类型的资料请关注自由互联其它相关文章!

    本文共计1782个文字,预计阅读时间需要8分钟。

    如何精确判断JavaScript中任意变量的具体数据类型?

    目录- 判断类型常用的方法 - typeof - instanceof - toString - 封装一个获取类型的函数 - typeof - instanceof - toString- 总结 - JS是弱类型语言,或者说动态语言 - 在定义变量时,我们不需要提前声明类型

    如何精确判断JavaScript中任意变量的具体数据类型?

    目录
    • 判断类型常用的方法
      • typeof
      • instanceof
      • toString
    • 封装一个获取类型的函数
      • typeof + instanceof(不推荐)
      • toString
    • 总结

      js是弱类型语言,或者说是动态语言,在定义变量时我们可以不提前声明变量的类型,也可以在变量声明后赋予不同类型的值。变量的类型会在程序运行的过程中被确定。对于开发者来说,虽然可以不用频繁的定义不同的数据类型,但是如果是比较复杂的项目,或者接手他人的项目,发现一个变量到处被使用并且赋予不同类型的值,也许头都大了。变量类型的不确定还可能出现运行时报错:xxx is not a function,根本原因就是不同的数据类型所具有的方法是不一样的,也许有的大家都有,因此不报错;但是如果是特有的,或者有差异的,不判断变量的类型就直接调用,就有可能出现生产bug。那么应该如何才能获取准确的变量类型呢?

      判断类型常用的方法

      typeof

      js内置的一个运算符,返回一个字符串,表示操作数的类型。可用于number、string、boolean等值类型,function函数,object等引用类型,如果是判断对象类型,则只能得到object,无法得到具体的值。

      console.log(typeof ''); // string console.log(typeof (() => {})); // function console.log(typeof Symbol()); // symbol console.log(typeof undefined); // undefined console.log(typeof null); // object console.log(typeof []); // object console.log(typeof {}); // object

      我们可以看到,数组、对象通过typeof都是返回了object,无法细分;其中值得注意的是typeof null结果也是object。这是因为在js的最初实现中,js中的值是由一个表示类型的标签以及实际数据值组合表示的。对象类型的标签是0,我们都知道null表示空,在大多数平台下其值为0x00,因此对象和null的类型标签是一样的。类型标签一样,但是null却没有正常对象的属性以及方法。

      instanceof

      instanceof也是js内置的一个运算符,用于判断两个参数之间是否存在联系,实现原理是检测构造函数的prototype属性是否出现在某个实例对象的原型链上。如果是,则返回true;否则,返回false。

      console.log({} instanceof Array); // false console.log([] instanceof Array); // true console.log({} instanceof Object); // true console.log([] instanceof Object); // true

      instanceof是判断两个参数,并不会直接获取变量的类型,可以通过枚举的方式简介获取。

      toString

      每一个对象都有一个toString()方法,因为每个对象都会继承自Object。可能在大多数人的印象中,toString()只是用来返回一个字符串,并没有什么特别的地方,那是因为你看到的toString()基本上都是被重写后的,原始的toString()是可以用来获取对象的类型的。

      举个例子:

      const o = new Object(); o.toString(); // [object Object] const arr = [1,2,3]; // 数组也会继承自Object arr.toString(); // '1,2,3',因为数组重写了toString

      每个对象都能通过Object.prototype.toString.call(thisArg)或者Object.prototype.toString.apply(thisArg)来获取其类型:

      console.log(Object.prototype.toString.call(null)); // [object Null] console.log(Object.prototype.toString.call(undefined)); // [object Undefined] console.log(Object.prototype.toString.call([])); // [object Array] console.log(Object.prototype.toString.call({})); // [object Object] console.log(Object.prototype.toString.call(() => {})); // [object Function]

      每次都调用js内置的API还是有点麻烦,所以我们还是封装一个函数getType

      封装一个获取类型的函数

      typeof + instanceof(不推荐)

      之前我们也提到了typeof可以获取部分数据类型,instanceof可以用枚举来表示剩下的类型,那么这两者结合是不是就可以实现getType了呢?

      function getType(obj) { if (typeof obj === 'object') { if (obj instanceof Array) return 'array'; if (obj instanceof Map) return 'map'; if (obj instanceof Set) return 'set'; if (obj instanceof RegExp) return 'regexp'; // 尽可能枚举类型,最后兜底返回object return 'object' } return (typeof obj); } console.log(getType(null)); // object console.log(getType(undefined)); // undefined console.log(getType('')); // string console.log(getType([])); // array console.log(getType(/a/)); // regexp console.log(getType(new WeakMap())); // object console.log(getType(new WeakSet())); // object

      使用此方式虽然可以实现getType,但是存在弊端;

      • 由于是枚举,导致代码长度可能会很长
      • 枚举的数据类型可能有限,未能覆盖常用数据类型
      • 如果要新增类型,则需要修改代码

      关于toString()的用法刚刚已经说了,我们以此来实现一个getType

      function getType(obj) { const originType = Object.prototype.toString.call(obj); // 获取类型。返回格式为[object type],需要提取出type的值 const firstSpaceIndex = originType.indexOf(' '); // 找到第一个空格所在下标 const type = originType.slice(firstSpaceIndex + 1, -1); // 跳过空格,截取到倒数第一个字符(不含最后一个) return type.toLowerCase(); // 转换为小写 } console.log(getType(null)); // null console.log(getType(undefined)); // undefined console.log(getType('')); // string console.log(getType([])); // array console.log(getType(/a/)); // regexp console.log(getType(new WeakMap())); // weakmap console.log(getType(new WeakSet())); // weakset

      实现getType我们也可以借助于操作数组的方式:

      function getType(obj) { const originType = Object.prototype.toString.call(obj); // 获取类型。返回格式为[object type],需要提取出type的值 const tmpType = originType.split(' ')[1]; // 根据空格分割,并取第二个 const type = tmpType.slice(0, -1); // 从0截取到倒数第一个字符(不含最后一个) return type.toLowerCase(); // 转换为小写 } console.log(getType(null)); // null console.log(getType(undefined)); // undefined console.log(getType('')); // string console.log(getType([])); // array console.log(getType(/a/)); // regexp console.log(getType(new WeakMap())); // weakmap console.log(getType(new WeakSet())); // weakset

      两者实现结果是一致的,基本上实现了我们的既定目标,而且可以获取到所有的数据类型。不同的是,操作数组比直接操作字符串更消耗性能。

      总结

      实现一个获取变量类型的方法,其实并不复杂,简单来说就是使用了内置的API:Object.prototype.toString()。有时候,往往就是因为过于简单而被我们忽略,其实越是简单的方式,才是越有效的。

      以上就是详解JavaScript如何准确获取任意变量的数据类型的详细内容,更多关于JavaScript获取变量数据类型的资料请关注自由互联其它相关文章!