为了使我的一个函数的语法更好,我需要能够判断一个特定的参数是一个数组还是"哈希"(我知道它只是对象).
Typeof不起作用,因为它们都返回相同的东西
typeof {foo:"bar"} // Object
typeof ["foo","bar"] // Object
那么我如何区分这两者呢?
我知道这有效,但我希望有更好的方法
({foo:"bar"}).constructor // Object()
(["foo","bar"]).constructor // [ undefined ]
编辑 啊,似乎[firebug中的[undefined]与Array是一样的.有点奇怪.
gbl*_*zex 11
你可以像SLaks建议的那样检查长度属性,但是一旦你传递了一个函数对象,你就会感到惊讶,因为它实际上有一个length属性.此外,如果对象定义了一个length属性,你将再次得到错误的结果.
你最好的选择可能是:
function isArray(obj) {
return Object.prototype.toString.call(obj) === "[object Array]";
}
Run Code Online (Sandbox Code Playgroud)
jQuery使用它,还有一对"其他人"...... :)
它比实例方式更失败.以下文章还建议了该方法:
'instanceof'被认为是有害的(或者如何编写一个强大的'isArray') (@ kagax)
另外要补充一点,这个功能几乎与Array.isArray
ES 5规范中的功能相同:
15.4.3.2 Array.isArray(arg)
- 如果Type(arg)不是Object,则返回 false.
- 如果arg的[[Class]]内部属性的值是"Array",则返回true.
- 返回false.
something instanceof Array
在单个文档中正常工作,但如果您开始在不同窗口之间传递数组,则会失败,因为Array
一个窗口与另一个窗口是不同的对象Array
.如果你不打算做跨窗口脚本(一般来说,值得避免),我建议坚持这一点.
如果您需要跨窗口支持,事情就会复杂一些.在未来,故事很简单,因为ECMAScript第五版定义了一个函数来完成这个:
Array.isArray([1]); // -> true
Run Code Online (Sandbox Code Playgroud)
您应该使用此功能,因为它是唯一可靠且标准认可的方式.但是,今天的许多浏览器还不支持它.
如果它不可用,你必须依赖Object#toString
序列化,这是丑陋和略有狡猾.虽然它通常可以与当今的浏览器一起可靠地工作,但是可以想象它可能不会(主要与宿主对象有关).
您可以将此回退方法放入Array
不支持它的浏览器中,然后Array.isArray
随时使用:
if (!('isArray' in Array)) {
Array.isArray= function(o) {
return Object.prototype.toString.call(o)==='[object Array]';
};
}
Run Code Online (Sandbox Code Playgroud)
至于constructor
,永远不要使用它.它并非在任何地方都可用,它没有按照您的想法行事.使用它几乎总是一个错误.
归档时间: |
|
查看次数: |
2355 次 |
最近记录: |