2016-04-21 85 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