JavaScript 面试题
目录

如何判断一个变量是否为数组?请写出至少三种方法。

· 约 4 分钟读完 · 第 5 / 507 章

推荐答案

本题详细解读

方法一:Array.isArray()

  • 原理: Array.isArray() 是 ES5 中新增的静态方法,它会直接检查传入的变量是否为数组。这是最直接、最推荐的方法。
  • 优点:
    • 简单易用,语义明确。
    • 兼容性好,除了旧版本浏览器(IE8 及以下)都需要 polyfill,但在现代浏览器中可以放心使用。
    • 性能好,原生方法效率高。
  • 缺点:
    • 对于 IE8 及以下浏览器需要使用 polyfill。
  • 使用场景: 推荐在所有现代浏览器中使用。

方法二:instanceof 操作符

  • 原理: instanceof 操作符用于检测构造函数的 prototype 属性是否存在于某个实例对象的原型链上。 如果 variable 的原型链上存在 Array.prototype,则返回 true。
  • 优点:
    • 简单直观,容易理解。
  • 缺点:
    • 在跨框架(iframe)中,由于不同的执行环境有不同的 Array 构造函数,可能会导致误判。例如,一个 iframe 创建的数组在主窗口中检测时,instanceof 返回 false。
    • 容易被子类覆盖,修改原型链后可能出现错误的结果。
  • 使用场景:
    • 在没有跨框架的情况下可以使用。
    • 不推荐在复杂环境中使用,尤其是有可能出现原型链污染的情况。

方法三:Object.prototype.toString.call()

  • 原理: Object.prototype.toString() 方法返回一个表示该对象的字符串。默认情况下,会返回 [object Class],其中 Class 表示对象的类型。通过使用 call() 方法,可以改变 this 的指向,将待检测的变量传给 toString(),从而获取该变量的准确类型字符串。对于数组,会返回 [object Array]。
  • 优点:
    • 通用性强,可以准确判断所有内置类型和自定义类型。
    • 不受跨框架影响。
    • 不受原型链影响,相对来说更可靠。
  • 缺点:
    • 语法稍微复杂,需要使用 call() 来调用。
    • 效率略低于前两种方法,但影响很小。
  • 使用场景:
    • 适用于所有场景,尤其是在跨框架或者需要严谨判断类型的情况下,建议使用。

一般来说,推荐优先使用 Array.isArray() 方法,在不支持该方法的旧版本浏览器中使用 Object.prototype.toString.call() 进行替代,避免使用 instanceof。