JavaScript 判断是否为数组
JavaScript 判断数组的几种方法及其利弊。
1. typeof
对于 Function、String、Number、Undefined 等几种类型的对象来说,他完全可以胜任。但是为 Array 时:
var arr = [1, 2, 3] console.log(typeof arr) // "object" // 同样的 console.log(typeof null) // "object" console.log(typeof {}) // "object"
所以不能使用 typeof
来判断。
2. instanceof
instanceof
运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上。
var arr = [1, 2 ,3] console.log(arr instanceof Array) // true
3. 原型链(constructor)
一般情况下,除了 undefined
和 null
,其它都能使用 constructor
判断类型。
var arr = [1, 2, 3] console.log(arr.__proto__.constructor === Array) // true console.log(arr.constructor === Array) // true // 注意:arr.__proto__ === Array.prototype 为 true。
但是某些情况下,判断是不准确的,比如:
// 构造函数 function Fn() {} // 修改原型对象 Fn.prototype = new Array() // 实例化对象 var fn = new Fn() console.log(fn.constructor === Fn) // false console.log(fn.constructor === Array) // true // 此时的 fn 应该是一个普通对象,而非数组,所以此时使用 constructor 判断是不合适的。
使用 instanceof 和 constructor 的局限性
使用和声明都必须是在当前页面,比如父页面引用了子页面,在子页面中声明了一个 Array
,将其赋值给父页面的一个变量,那么此时做原型链的判断:Array === object.constructor
得到的是 false
,原因如下:
Array
属于引用型数据,在传递过程中,仅仅是引用地址的传递。- 每个页面的
Array
原生对象所引用的地址是不一样的,在子页面声明的Array
所对应的构造函数是子页面的Array
对象;父页面来进行判断,使用的Array
并不等于子页面的Array
。
附上 Categorizing values in JavaScript 的一段原话:
Array.isArray()
exists because of one particular problem in browsers: each frame has its own global environment. An example: Given a frame A and a frame B (where either one can be the document). Code in frame A can pass a value to code in frame B. Then B code cannot useinstanceof Array
to check whether the value is an array, because its BArray
is different from the AArray
(of which the value could be an instance).
看代码:
var iframe = document.createElement('iframe') document.body.appendChild(iframe) var xArray = window.frames[window.frames.length - 1].Array var xarr = new xArray() var arr = new Array() // 不同页面,结果并非我们所预期的 true,而是 false 哦! console.log(xarr instanceof Array) // false console.log(xarr.constructor === Array) // false // 同页面才是 true 哦! console.log(arr instanceof Array) // true console.log(arr.constructor === Array) // true
4. Array.isArray
鉴于以上原因,ES5 标准提供的一个判断数组方法 isArray()
,其原理也是通过 Object.prototype.toString()
判断对象的内部属性 [[Class]]
是否为 "Array"
,以达到判断数组的目的。
function isArray(arr) { return Array.isArray(arr) }
5. Object.prototype.toString
所以,终极方法就是以下这个
function isArray(arr) { return Object.prototype.toString.call(arr) === '[object Array]' }
参考
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论