2017-07-18 24 views
5

最近我調查的情況是程序員無意中傳遞undefined到的addEventListener,從而類型:無法確定的未定義()

window.addEventListener('load', undefined); 

沒有錯誤被拋出。就好像JavaScript願意調用undefined。但是世界上什麼undefined()?我已經嘗試了各種各樣的東西,例如:

console.log(undefined() === null); 
console.log(typeof undefined()); 

但我從來沒有得到任何回報。

編輯添加清晰度:我原來的問題是基於一個錯誤,因爲我沒有設置我的開發人員工具將錯誤記錄到控制檯。以上兩個命令(但不是addEventListener的調用)會在瀏覽器中拋出錯誤,如下面的答案和註釋所示。

+0

未定義不是一個類型,它是未定義的。 – T4rk1n

+0

我知道'undefined'不是一個類型。我的問題是關於'undefined()'的狀態,它在JavaScript中沒有引發語法錯誤。 –

+0

它很奇怪 - 如果你只是試圖在控制檯中調用undefined作爲一個函數,它會拋出一個錯誤,但是如果我將任何非函數作爲回調函數傳遞給'addEventListener',它只會默默地失敗,並且不會引發錯誤... –

回答

2

It's as if JavaScript is willing to invoke undefined .

不,addEventListener is specified to ignore null,which JavaScript’s undefined is converted toundefined永遠不會被調用。

進一步證明了JavaScript是不願意援引undefined,在瀏覽器中:

> undefined() 
Uncaught TypeError: undefined is not a function 
    at <anonymous>:1:1 
+1

我想在正確的軌道上,但似乎瀏覽器可能超出了規範,因爲我可以用其他非函數來做 - 比如' document.addEventListener('click',3)' - 瀏覽器沒有抱怨它傳遞了一個非函數,但是當我然後點擊文檔時它不會引發任何錯誤... –

+0

是的,也許這正是瀏覽器容忍的地方。我剛剛在Node中嘗試了'console.log(undefined())'並得到了「參考錯誤:undefined不是函數。」 –

+0

@AlexanderNied:啊,這是Chrome的事情。 Firefox只忽略'null'和'undefined'。 – Ryan

0

它將返回:

Undefined is not a function

console.log(typeof undefined());

如果你運行它控制檯在瀏覽器上會返回undefine d不是功能。未定義沒有任何價值,不同於null這是一個對象。

+0

是的,在Node中,但不在我的瀏覽器中。見下面的評論回答。我認爲我們已經把它固定下來,嚴格來說是一個瀏覽器容忍的錯誤。 –

+1

@HomerWhite:'undefined()'一定會在瀏覽器中拋出一個錯誤。你可能沒有在正確的位置尋找錯誤......? – Ryan

+1

爲了清晰起見,我建議將代碼片段更改爲undefined()。有些人可能會誤解,其餘的背景是無​​關緊要的。 –

0

null意味着有東西存在,但被告知它沒有價值。 undefined意味着事物沒有被賦予一個值,通常是因爲它沒有被聲明/初始化。

在Javascript中,undefined是一個原始的。這是錯誤的,所以如果在條件中使用它,它的計算結果爲False

Javascript不是強類型語言,所以沒有什麼可以檢查回調函數是否爲函數直到它被調用。事實上,Javascript並不在乎有多少參數被傳遞或者它們的類型是什麼,當一個函數被調用時,所有的東西都被拋棄了,這取決於函數如何處理參數。

例如在許多枚舉方法中,它們會傳回給您(index, value, array)。無論你的函數是查找這些值還是給它們分配一個臨時變量都沒有關係,它們仍然通過。 a.forEach(function(index){}) and a.forEach(function(){})實際上都可以訪問所有提到的3個變量。

+1

*「Javascript不是一種類型化的語言,因此沒有什麼可以檢查回調函數是一個函數。」* typeof'怎麼樣?無論如何,如果你試圖在沒有*檢查的情況下調用非函數*,它會拋出一個錯誤,而不是默默地失敗。 – Ryan

0

你可以做這樣的事情找到傳遞的參數類型:

var myVar; 

Object.prototype.toString.call(myVar); 

,它將返回"[object Undefined]"

同樣用於其他用途的情況一樣,如果myVar是一個字符串如下:

var myVar = 'It is a string'; 
Object.prototype.toString.call(myVar); 

它會逆轉"[object String]"