2017-04-25 108 views
2

我一直在使用相同的JavaScript庫我已經建立了多年,現在我遇到了這個函數錯誤:未定義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

我加定義標準變量來解決這個問題如下之前:

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

但是,我想了解如何或爲什麼會發生這種情況。我不知道爲什麼一個具有'對象'類型的變量不會有構造函數。在這個問題之前我從未見過它。關於這一點我感到困擾的是,這一切都是在我更新另一個庫函數後開始的,這些函數檢查空值和空字符串以嘗試過濾空數組(將空數組與空字符串進行比較時,它會返回一個匹配項) 。

+5

'null'是typeof對象的類型。 – Li357

回答

1

呃......你可能知道,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回報對象null == undefined回報真正 .. 。

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

+1

ES5確實有'Array.isArray'。只有在古代,這真的很難。 – Bergi

+0

好評,謝謝!你是對的。由於某些原因,我的思想在這個主題上混合了三個規範......我認爲'Array.isArray()'是ES6的一部分,就像'Array.from()',但它是ES5的一部分。上面的代碼在ES3和較老的polyfills中很有用。我會編輯我的答案。 :) – Badacadabra

+0

我不得不測試這個,因爲我正在使用服務器端JavaScript引擎,但它的確有用。我的方法一直工作多年,所以我很高興現在可以使用它。奇怪的是,它使用了一個像[「」,「」,「」]定義的數組,然後與另一個類似的數組失敗了幾行。這麼奇怪。 –