开发者问题收集

未定义的 JavaScript 对象构造函数

2017-04-25
4773

多年来,我一直在使用自己构建的同一个 JavaScript 库,现在遇到了此函数的错误:

IsArray : function ()
{
    if (typeof arguments[0] == 'object')
    {
        var criterion = arguments[0].constructor.toString().match(/array/i);
        return (criterion != null);
    }

    return false;
}

有时在调用它时会抛出以下错误:

TypeError: Cannot call method "toString" of undefined

在定义 criterion 变量之前,我添加了以下内容来解决问题:

if (arguments[0].constructor == null || arguments[0].constructor == undefined)
    return false;

但是,我想了解这种情况是如何或为什么会发生的。我不知道为什么具有“对象”类型的变量没有构造函数。在出现此问题之前,我从未见过这种情况。让我感到困扰的是,这一切都是在我更新另一个库函数几周后开始的,该函数检查空值和空字符串以尝试过滤掉空数组(当将空数组与空字符串进行比较时,它会返回匹配项)。

2个回答

嗯...您可能知道,JavaScript 有时有点令人惊讶。使用 ES3,判断数组是否真的是数组并不容易。因此,如果您想保留您的遗留代码,我认为您应该遵循 Douglas Crockford JavaScript:The Good Parts 中给出的重要提示。

JavaScript does not have a good mechanism for distinguishing between arrays and objects. We can work around that deficiency by defining our own is_array function:

var is_array = function (value) {
  return value && typeof value === 'object' && value.constructor === Array;
};

Unfortunately, it fails to identify arrays that were constructed in a different window or frame. If we want to accurately detect those foreign arrays, we have to work a little harder:

var is_array = function (value) {
  return Object.prototype.toString.apply(value) === '[object Array]';
};

此外,您在使用 null 时应该非常小心,因为 Object.create(null) 会创建一个没有任何原型的对象, typeof null 返回 object 并且 null == undefined 返回 true ...

使用 ES5,最好的解决方案是使用 Array.isArray()

Badacadabra
2017-04-25

并非所有对象都具有 .constructor 属性,例如 Object.create(null) ,就像 并非所有对象都具有 toString 方法 一样。

对于您的 IsArray 函数,您应该使用本机 Array.isArray 方法或其常用 polyfill。

Bergi
2017-04-25