likes
comments
collection
share

让我们浅浅的了解一下JavaScript中的类型判断

作者站长头像
站长
· 阅读数 3

前言

当我们在处理 JavaScript 中的数据类型时,有几种常见的方式来进行判断。了解这些方法的特点和用法可以帮助我们更好地处理不同类型的数据。接下来让我们一起来看看JavaScript中都有哪些方法可以判断数据类型。

typeof

typeof 操作符是 JavaScript 中用于确定变量或值的数据类型的一种方法。它返回一个字符串,表示被检测值的数据类型。typeof可以准确判定原始类型,null除外;但是无法判定引用类型,除了function,都会被判定为object。下面是关于 typeof 操作符的一些讲解。

1. 原始类型判断

对于 JavaScript 中的原始类型:

  • typeof 可以准确识别 numberstringbooleanundefinedsymbol 类型。

    • 示例:
      typeof 21;          // 返回 "number"
      typeof 'Hello';     // 返回 "string"
      typeof true;        // 返回 "boolean"
      typeof undefined;   // 返回 "undefined"
      typeof Symbol();   // 返回 "symbol"
      
  • 但对于 null 类型,typeof 的行为有点特殊,它将 null 归类为 'object'

    • 示例:
      typeof null;    // 返回 "object"(注意这是 JavaScript 的历史遗留问题,不是预期行为)
      

2. 引用类型判断

对于引用类型(Reference Types):

  • 对于除了 function 以外的引用类型(比如对象、数组等),typeof 会将它们归类为 'object'

    • 示例:
      typeof { a: 1 };        // 返回 "object"
      typeof [1, 2, 3];       // 返回 "object"
      typeof new Date();      // 返回 "object"
      
  • 特殊的对于函数类型,typeof 会返回 'function'

    • 示例:
      typeof function() {};   // 返回 "function"
      

3. 注意事项

  • typeof 返回的是一个字符串,它提供了变量或值的基本数据类型信息,可用于条件语句或类型判断。
  • typeof 在某些情况下可能不够准确,特别是在涉及到 null 和引用类型的判断时会导致错误判断。
  • typeof 通常用于检查变量是否已声明或未定义,或者用于确定变量类型以便执行相应的操作。
  • 因此在日常使用时要注意考虑null和引用类型的判断情况。

instanceof

instanceof 操作符是 JavaScript 中用于检查对象是否属于某个特定类型(构造函数)的实例的方法。语法为:object instanceof a。它的工作原理是通过检查对象的原型链来确定对象是否是某个构造函数的实例。下面是关于instanceof操作符的一些讲解。

  • instanceof的原理:instanceof操作符用来测试一个对象在其原型链中是否存在一个构造函数的prototype属性,因此,instanceof的运算规则是:在原型链上查找,直到找到对象的原型对象,如果原型对象的prototype和类型的prototype相同,则返回true,否则返回false
  • 缺点:无法判断两个不同的全局执行上下文中创建的对象,因为两个全局执行上下文中的原型链是不同的,所以无法判断
  • 示例:
let obj = {}//true
let arr = []//true
let date = new Date()//true
let fn = function () { }//true


console.log(obj instanceof Object);//true obj.__proto__ === Object.prototype
console.log(arr instanceof Array);//true arr.__proto__ === Array.prototype
console.log(arr instanceof Object);//true arr.__proto__.__proto__ === Object.prototype
console.log(date instanceof Date);//true date.__proto__ === Date.prototype
console.log(fn instanceof Function);//true fn.__proto__ === Function.prototype

如上述代码所示:

  • obj instanceof Object 返回 true,因为所有对象(包括空对象 {})都是 Object 构造函数的实例。
  • arr instanceof Array 返回 true,因为数组是通过 Array 构造函数创建的,数组的原型链中包含 Array.prototype
  • arr instanceof Object 返回 true,因为数组也是对象,而对象的原型链上一级是 Object.prototype
  • date instanceof Date 返回 true,因为 date 是通过 Date 构造函数创建的,Date.prototypedate 的原型链上。
  • fn instanceof Function 返回 true,因为函数是通过 Function 构造函数创建的,Function.prototype 在函数的原型链上。

总之,instanceof 是通过检查对象的原型链来确定对象是否是特定构造函数的实例,对于不同类型的对象,它可以帮助确定对象的类型关系。

实现方法

以下是instanceof操作符的实现方法:

function myInstanceof(L,R) { //L,R表示待检查对象和目标对象
  let left = L.__proto__ //初始化 `left` 变量为 `L` 对象的原型
  let right = R.prototype //初始化 `right` 变量为构造函数 `R` 的 `prototype` 属性
  while (left !== null) {
    if(left === right) {
      return true
    }
   // 如果 `left` 与 `right` 相等,即当前原型与构造函数的 `prototype` 相等,
   //表示 `L` 是 `R` 的一个实例,此时返回 `true`。
    left = left.__proto__ //若当前原型不符合条件,将 `left` 设置为其自身的原型,继续向上查找原型链。
  }
  return false
}
console.log(myInstanceof([], Array));//true arr.__proto__ === Array.prototype
console.log(myInstanceof([], Object));//true arr.__proto__.__proto__ === Object.prototype

上述代码定义了一个 myInstanceof 函数使用遍历的方式用于实现instanceof操作符。

Object.prototype.toString()

Object.prototype.toString() 方法是 JavaScript 中用来确定对象的类型的一种方法。它可以对 JavaScript 中的各种数据类型进行更精确的类型判断,包括原始类型和引用类型。

  • 原理:

    • Object.prototype.toString() 返回一个表示传递给它的对象的类型的字符串。

    • toString() 方法以默认方式被调用时(即未通过 call() 显式指定 this),它返回 [object Object]

    • 但当我们使用 call() 来改变 this 的指向时,它就会返回更精确的类型信息

  • 示例:

Object.prototype.toString.call(21);        // 返回 "[object Number]"
Object.prototype.toString.call('Hello');   // 返回 "[object String]"
Object.prototype.toString.call(true);     // 返回 "[object Boolean]"
Object.prototype.toString.call([]);       // 返回 "[object Array]"
Object.prototype.toString.call({});       // 返回 "[object Object]"
Object.prototype.toString.call(null);     // 返回 "[object Null]"
Object.prototype.toString.call(undefined);// 返回 "[object Undefined]"
Object.prototype.toString.call(new Date());// 返回 "[object Date]"

注意:如果传的是原始类型,那就会调用ToObject将原始类型转换为对象

Array.isArray()

Array.isArray() 是 JavaScript 中用于检查一个值是否为数组的方法。它只能用来判断数组类型。

  • 原理: Array.isArray() 检查传递给它的参数是否属于数组类型,返回一个布尔值,如果是数组类型则返回 true,否则返回 false

  • 示例:

Array.isArray([]);            // 返回 true
Array.isArray([1, 2, 3]);     // 返回 true
Array.isArray(new Array());   // 返回 true
Array.isArray('hello');       // 返回 false
Array.isArray(123);            // 返回 false
Array.isArray({});            // 返回 false
Array.isArray(null);          // 返回 false
Array.isArray(undefined);     // 返回 false

相较于其他类型检查的方法,如 typeofinstanceofArray.isArray() 提供了更准确的数组类型检查。并且Array.isArray() 不会受到不同全局执行上下文中原型链的影响。总的来说,Array.isArray() 是一种方便且可靠的方法,用于判断一个值是否为数组类型。

结语

综上,在 JavaScript 中,对于类型判断有着typeofinstanceofObject.prototype.toString()Array.isArray() 的判断方法。其中typeof 适用于原始类型,instanceof 判断引用类型,但需注意其局限性。Object.prototype.toString()可以提供更精确的类型判断信息,而 Array.isArray() 可以更准确地判断数组。