Javascript 闭包编译器警告“危险使用此对象的全局对象”?
亲爱的朋友们,闭包编译器在高级模式下给出此警告,并在Javascript 闭包编译器警告“危险使用此对象的全局对象”?,javascript,jquery,debugging,google-closure-compiler,Javascript,Jquery,Debugging,Google Closure Compiler,亲爱的朋友们,闭包编译器在高级模式下给出此警告,并在{this. JSC_使用了_GLOBAL_THIS:危险地使用第200行字符33处的全局THIS对象 hover[i4].onfocus=function(){this.className+=“hover”} JSC_使用了_GLOBAL_THIS:危险地使用第201行字符32处的全局THIS对象 悬停[i4].onblur=function(){this.className=this.className.replace(/Hove… JSC
{this.
JSC_使用了_GLOBAL_THIS:危险地使用第200行字符33处的全局THIS对象
hover[i4].onfocus=function(){this.className+=“hover”}
JSC_使用了_GLOBAL_THIS:危险地使用第201行字符32处的全局THIS对象
悬停[i4].onblur=function(){this.className=this.className.replace(/Hove…
JSC_使用了_GLOBAL_THIS:危险地使用了第201行字符49处的全局THIS对象
悬停[i4].onblur=function(){this.className=this.className.replace(/Hove…
JSC_使用了_GLOBAL_THIS:危险地使用第218行字符38处的全局THIS对象
按钮[i5].onmouseover=function(){this.className+=“悬停”}
Q1.这有什么危险?Q2.我应该改变这个吗?
Q3.如何改进/解决此代码? 谢谢!“这个”在不同的上下文中可能有不同的含义,所以它确切地告诉您。 您可以改为使用闭包: 而不是
hovers[i4].onfocus = function() {this.className += "Hovered";}
拥有:
如果您知道“this”变量的类型,可以使用JsDoc声明它,以阻止编译器抱怨:
hovers[i4].onfocus =
/** @this {Element} */
function() {this.className += "Hovered";}
警告:但是,这假设您确实知道“this”变量的类型。这可能不像看上去那么容易。例如:
foo.doSomething = function(x) { this.bar = x; }
foo.doSomething("Hello");
您应该知道,doSomething
中的“this”指的是foo
。但是,如果您使用闭包编译器的高级模式,编译器可能会“展平”foo
命名空间,您将得到:
a = function(x) { this.b = x }
a("Hello");
foo.doSomething
被“展平”为单个全局变量a
。在这种情况下,“this”变量显然指向全局对象!您的代码将被破坏
因此,闭包编译器非常坚决地警告您不要在可以展平的函数中使用“this”。不过,您可以在构造函数和原型函数中使用“this”,而不使用此警告
要解决此问题,最好通过使用名称空间本身来避免使用“this”:
foo.doSomething = function(x) { foo.bar = x; }
foo.doSomething("Hello");
只是为了举例说明@marcinkuzminski对@stephen Chung answer的评论
/**
* Model for ListBox
*
* @constructor <-- add this to remove the warning
*/
MyProject.ListBoxModel = function ( data ){
this.data_ = data || {}; /* this gives warning */
};
/**
*列表框模型
*
*@constructor“this的危险用法”并不是试图警告用户“this”在不同上下文中的不同含义。它是一个警告,告诉用户,如果编译器决定展平命名空间,“this”的任何用法将指向错误的对象并将破坏代码。这纯粹是一个警告,与编译器执行的优化有关。@Stephen Chung:嗯,我的意思是相同的。如果你认为我说错了,请随意编辑我的答案-英语不是我的第一语言,我可能会把事情的措辞弄错:)对于任何定义类的函数,您都应该使用@constructor is JSDoc来消除此警告。这是google为此类警告推荐的方法。这也是一篇较老的文章,有一个更具体的问题和一些很好的答案。
/**
* Model for ListBox
*
* @constructor <-- add this to remove the warning
*/
MyProject.ListBoxModel = function ( data ){
this.data_ = data || {}; /* this gives warning */
};