我一直在使用我已经构建多年的同一个JavaScript库,现在我遇到了这个函数的错误:
IsArray : function ()
{
if (typeof arguments[0] == 'object')
{
var criterion = arguments[0].constructor.toString().match(/array/i);
return (criterion != null);
}
return false;
}
有时会在抛出以下错误时调用它:
TypeError:无法调用方法" toString"未定义的
我在定义标准变量之前添加了以下内容以解决此问题:
if (arguments[0].constructor == null || arguments[0].constructor == undefined)
return false;
但是,我想了解这种情况将如何或为何会发生。我不知道为什么一个变量有一个'对象'没有构造函数。我在此问题之前从未见过它。令我困扰的是这一切都是在我更新另一个检查空值和空字符串以尝试过滤掉空数组的库函数几周后开始的(当将空数组与空字符串进行比较时,它返回一个匹配项)
答案 0 :(得分:1)
嗯......正如您所知,JavaScript有时会令人惊讶。使用ES3,确定数组是否实际上是一个数组并不容易。因此,如果您想保留遗留代码,我认为您应该遵循 JavaScript:好的部分中 Douglas Crockford 提供的重要提示。
JavaScript没有很好的区分机制 数组和对象。我们可以通过定义我们的方法解决这个问题 拥有is_array函数:
var is_array = function (value) {
return value && typeof value === 'object' && value.constructor === Array;
};
不幸的是,它无法识别在a中构造的数组 不同的窗口或框架。如果我们想要准确地检测出那些 国外阵列,我们必须更努力地工作:
var is_array = function (value) {
return Object.prototype.toString.apply(value) === '[object Array]';
};
此外,您在使用null
时应该非常小心,因为Object.create(null)
创建的对象没有任何原型,typeof null
返回对象和{{1 }}返回 true ...
使用ES5,最佳解决方案是使用null == undefined
。
答案 1 :(得分:0)
并非所有对象都具有.constructor
属性,例如Object.create(null)
,就像not all objects have a toString
method一样。
对于IsArray
函数,您应该使用原生Array.isArray
方法或其常用的polyfill。