2016-04-21 87 views
1

下面是一些代碼,我傳遞給谷歌關閉編譯一個非常簡化的版本:谷歌關閉編譯器抱怨XMLHttpRequest.response型

"use strict"; 

var xhr = new XMLHttpRequest(); 

xhr.open("GET", "somefile", true); 
xhr.responseType = "arraybuffer"; 

xhr.addEventListener(
    'load', 
    function() {  
    var data = new Uint8Array(xhr.response); 
    /* ... do something ... */ 
    } 
); 

這基本上是一個Ajax查詢檢索原始二進制數據和它按預期工作。

然而,編譯器發出如下警告:

WARNING - actual parameter 1 of Uint8Array does not match formal parameter 
found : * 
required: (Array<number>|ArrayBuffer|ArrayBufferView|null|number) 
     var data = new Uint8Array(xhr.response); 
           ^

我花了一些時間,試圖與JSDoc指令修正它,以明確定義的「xhr.response」的類型爲「ArrayBuffer 」。

例如:

/** @property {ArrayBuffer} response */ 
var xhr = new XMLHttpRequest(); 

但毫無效果。

什麼終於做的工作是變量聲明由它的初始化分開,不添加任何JSDoc指令:

var xhr; 
xhr = new XMLHttpRequest(); 

無警告了。

問題是我不明白。爲什麼它解決了這個問題?是否真的是正確的做法?

回答

1

爲什麼它解決了這個問題?

我想你已經在閉包編譯器中發現了一個bug。你可以關於它report an issue

將該行分成兩行不應改變編譯器正在執行的操作。爲了清楚起見,這裏是你分裂的路線。

var xhr; 
xhr = new XMLHttpRequest(); 

我證實使用online closure compiler與優化設置爲高級報告。

是否真的是正確的做法?

html5.js extern的定義是

/** 
* @type {*} 
* @see http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#the-responsetype-attribute 
*/ 
XMLHttpRequest.prototype.response; 

所以你得到的錯誤是合理的。有型鑄造修復:

var r = /** @type {!ArrayBuffer}*/(xhr.response); 
var data = new Uint8Array(r); 

嘗試在online closure compiler與優化設置爲高級以下。

"use strict"; 

var xhr = new XMLHttpRequest(); 

xhr.open("GET", "somefile", true); 
xhr.responseType = "arraybuffer"; 

xhr.addEventListener(
    'load', 
    function() { 
    var r = /** @type {!ArrayBuffer}*/(xhr.response); 
    var data = new Uint8Array(r); 
    /* ... do something ... */ 
    } 
); 

它對我有用。我也收到你用原始版本報告的錯誤。但請注意,如果優化設置爲「簡單」,我們不會收到錯誤。

+0

感謝您的分析和建議的修復。我以某種方式未能提供正確的語法'/ ** @type {!ArrayBuffer} * /(xhr.response)'。我想我沒有使用括號。 – Arnauld

+0

類型轉換絕對是正確的解決方案 - 它不是一個錯誤。 –

+0

@查德:是的,演員是正確的解決方案。但是,當我分割一行_without_type類型轉換時,警告消失的事實看起來非常像編譯器錯誤。 – Arnauld