
目录JavaScript 判断一个值是不是数组一、Array.isArray() ⭐⭐⭐⭐⭐基本用法为什么推荐二、instanceof ⭐⭐⭐⭐instanceof 是怎么判断的instanceof 的缺点三、Object.prototype.toString.call() ⭐⭐⭐⭐完整写法为什么要使用 call四、constructor为什么可以这样判断constructor 的问题五、Array.prototype.isPrototypeOf()它是什么意思六、几种方法对比七、实际开发到底用哪个第一选择Array.isArray()八、面试需要知道的区别九、不要用 typeof 判断数组十、一个容易混淆的知识点十一、推荐记忆顺序十二、最终结论 ⭐最推荐经典方法经典类型判断不太推荐不推荐用于判断数组一句话记忆JavaScript 判断一个值是不是数组在 JavaScript 中判断一个值是不是数组有多种方法。最常见的有Array.isArray()instanceofObject.prototype.toString.call()constructorArray.prototype.isPrototypeOf()其中实际开发中最推荐Array.isArray(value)一、Array.isArray() ⭐⭐⭐⭐⭐这是现代 JavaScript 中最推荐、最标准的判断数组方法。constarr[1,2,3]Array.isArray(arr)// true不是数组Array.isArray(hello)// falseArray.isArray({})// falseArray.isArray(null)// falseArray.isArray(undefined)// false基本用法Array.isArray(value)例如functionisArray(value){returnArray.isArray(value)}isArray([1,2,3])// trueisArray({})// false为什么推荐因为它就是 JavaScript 专门用来判断数组的方法。而且它可以正确处理不同 JavaScript Realm例如 iframe中的数组。Array.isArray([])// true二、instanceof ⭐⭐⭐⭐instanceof可以用来判断一个对象是否属于某个构造函数的实例。constarr[1,2,3]arrinstanceofArray// true例如constarr[]console.log(arrinstanceofArray)// true普通对象constobj{}console.log(objinstanceofArray)// false字符串conststrhelloconsole.log(strinstanceofArray)// falseinstanceof 是怎么判断的可以简单理解为沿着对象的原型链一直往上找看能不能找到Array.prototype。例如constarr[]arrinstanceofArray大致可以理解成arr ↓ Array.prototype ↓ Object.prototype ↓ null因为找到了Array.prototype所以arrinstanceofArray// trueinstanceof 的缺点在不同的 JavaScript Realm 中可能出现问题。例如浏览器中的 iframe主页面 │ ├── Array │ └── iframe └── Array虽然两个Array都是数组构造函数但它们属于不同的 Realm。因此可能出现arrFromIframeinstanceofArray// false但Array.isArray(arrFromIframe)// true所以实际开发中判断数组优先使用Array.isArray()。三、Object.prototype.toString.call() ⭐⭐⭐⭐这是 JavaScript 中非常经典的类型判断方式。Object.prototype.toString.call(value)数组constarr[1,2,3]Object.prototype.toString.call(arr)// [object Array]所以可以这样判断Object.prototype.toString.call(arr)[object Array]// true完整写法functionisArray(value){returnObject.prototype.toString.call(value)[object Array]}测试isArray([])// trueisArray({})// falseisArray(hello)// falseisArray(null)// falseisArray(undefined)// false为什么要使用 call因为Object.prototype.toString本质上是一个函数。我们需要让它针对我们传入的对象执行。所以Object.prototype.toString.call(arr)相当于Object.prototype.toString.call(你要判断的值)例如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(hello)// [object String]Object.prototype.toString.call(123)// [object Number]所以它不仅可以判断数组还可以进行更加细致的类型判断。四、constructor还可以通过对象的constructor判断。constarr[]arr.constructorArray// true例如functionisArray(value){returnvalue?.constructorArray}测试isArray([])// trueisArray({})// falseisArray(hello)// false为什么可以这样判断数组的构造函数是Array所以[].constructor通常就是Array因此[].constructorArray// trueconstructor 的问题constructor可以被修改。例如constarr[]arr.constructorObject console.log(arr.constructorArray)// false这时候数组明明还是数组Array.isArray(arr)// true但是arr.constructorArray// false所以constructor可以了解但不推荐用它作为正式的数组判断方式。五、Array.prototype.isPrototypeOf()还可以使用Array.prototype.isPrototypeOf(value)例如constarr[]Array.prototype.isPrototypeOf(arr)// true普通对象constobj{}Array.prototype.isPrototypeOf(obj)// false它是什么意思可以理解成判断Array.prototype是不是这个对象原型链上的某一层。例如constarr[]原型链大致是arr ↓ Array.prototype ↓ Object.prototype ↓ null因此Array.prototype.isPrototypeOf(arr)// true六、几种方法对比方法示例推荐程度主要问题Array.isArray()Array.isArray(value)⭐⭐⭐⭐⭐基本没有instanceofvalue instanceof Array⭐⭐⭐⭐跨 iframe / Realm 可能失效Object.prototype.toString.call()Object.prototype.toString.call(value)⭐⭐⭐⭐写法稍长constructorvalue.constructor Array⭐⭐constructor可以被修改Array.prototype.isPrototypeOf()Array.prototype.isPrototypeOf(value)⭐⭐不常用七、实际开发到底用哪个第一选择Array.isArray()绝大多数情况下直接Array.isArray(value)例如if(Array.isArray(data)){console.log(data 是数组)}这是最推荐的写法。八、面试需要知道的区别如果面试官问JavaScript 怎么判断一个值是不是数组可以回答Array.isArray(value)这是最推荐的方法。还可以使用valueinstanceofArray或者Object.prototype.toString.call(value)[object Array]但是instanceof在跨 iframe / Realm 的情况下可能出现问题。而constructorArray不够可靠因为constructor属性可以被修改。因此实际开发优先Array.isArray(value)九、不要用 typeof 判断数组很多刚学习 JavaScript 的人会想到typeof[]结果是object所以typeof[]array// false因为 JavaScript 中typeof[]// objecttypeof{}// objecttypeofnull// object所以typeof无法区分数组和普通对象。十、一个容易混淆的知识点数组本质上也是对象。typeof[]// object所以可以理解成JavaScript │ ├── 原始类型 │ ├── string │ ├── number │ ├── boolean │ ├── undefined │ ├── bigint │ ├── symbol │ └── null │ └── Object │ ├── 普通对象 {} ├── Array [] ├── Function ├── Date ├── RegExp ├── Map ├── Set └── ...所以typeof[]// object并不代表数组不是数组。它只是说明数组属于 Object 这一大类对象。十一、推荐记忆顺序如果你正在系统学习 JavaScript 类型判断可以按照这个顺序记typeof ↓ instanceof ↓ constructor ↓ Object.prototype.toString.call() ↓ Array.isArray() ↓ 原型链 ↓ 跨 Realm / iframe其中最重要的是typeof用于判断基础类型。instanceof用于判断原型链上的实例关系。Object.prototype.toString.call()用于更加精确地判断类型。Array.isArray()专门用于判断数组。十二、最终结论 ⭐如果只是想判断value是不是数组。直接写Array.isArray(value)即可。最推荐Array.isArray(value)经典方法valueinstanceofArray经典类型判断Object.prototype.toString.call(value)[object Array]不太推荐value.constructorArray不推荐用于判断数组typeofvaluearray因为typeof[]object一句话记忆判断数组首选Array.isArray()instanceof看原型链toString.call()看精确类型constructor不够可靠typeof判断不了数组。