在JavaScript中为Google闭包编译器注释单例对象,或者“危险地使用全局this对象”.警告
Annotate Singleton objects in JavaScript for the Google Closure Compiler, or "dangerous use of the global this object" warning
我正在使用Google Closure Compiler in ADVANCED_OPTIMIZATIONS编译级别,并且已经开始注释我的构造函数,因为我得到了各种各样的警告:
警告-使用全局this对象
是危险的
对于我的"构造函数"类型的函数,我将像这样注释它们:
/**
* Foo is my constructor
* @constructor
*/
Foo = function() {
this.member = {};
}
/**
* does something
* @this {Foo}
*/
Foo.prototype.doSomething = function() {
...
}
这似乎工作得很好,但是,如果我有一个'单例'对象,不是用var myFoo = new Foo()构造;我在文档中找不到如何注释这种类型的对象因为它的类型就是对象,对吧?
Bar = {
member: null,
init: function() {
this.member = {};
}
};
在Closure中创建单例的首选方式如下:
/** @constructor */
var Bar = function() { };
goog.addSingletonGetter(Bar);
Bar.prototype.member = null;
Bar.prototype.init = function() {
this.member = {};
};
允许单例的延迟实例化。像这样使用:
var bar1 = Bar.getInstance();
var bar2 = Bar.getInstance();
bar1.init();
console.log(bar2.member);
请记住,这并不妨碍人们使用构造函数来创建Bar
的实例。
正是"危险使用This "警告您要注意的潜在错误类型。在您的示例中,闭包编译器可能会尝试将您的代码"扁平化"为:
Bar$member = null;
Bar$init = function() { this.member = {}; };
注意:闭包编译器目前不会扁平化被声明为全局对象的命名空间(即前面没有"var"关键字),所以你的代码现在可能仍然可以工作。然而,没有人知道它不会在未来的版本中这样做,你的代码会在没有警告的情况下突然中断。
当然,那么"Bar$member"answers"Bar$init"将分别重命名为"a"answers"b"。这被称为"命名空间平坦化"或"属性折叠"。
您可以立即看到您的代码不再正常工作。在编译之前,如果您写:
Bar.init();
this
指Bar
。但是,编译后它变成:
Bar$init();
this
将不再指代Bar
。而是指向全局对象。
这是编译器试图警告你以这种方式使用"This"是"危险的",因为"This"可能被更改为指向"global"对象。这才是警告的真正含义。
简而言之,不要这样做。这种类型的编码风格产生的bug 非常难以追踪。
这样修改你的代码:
var Bar = { // Closure Compiler treats globals and properties on global differently
member: null,
init: function() { Bar.member = {}; }
};
或使用闭包:
var Bar = (function() {
var member = null;
return {
init: function() { member = {}; }
};
})();
在高级模式下使用闭包编译器时,不要试图通过注释来消除警告。警告的存在是有原因的——它们试图警告你一些事情。
- 引用对象中的通用值
- jQuery匹配JSON对象的部分文本
- 节点导出返回一个空对象
- 如何在Javascript中将JSon对象转换为数组
- 我可以在json对象中添加一个函数吗
- 使用JS将数组转换为json对象
- 全局变量和全局对象的属性之间有什么区别吗
- 比较从函数和生成的日期对象
- Javascript,访问一个主要对象模块模式中的每个对象
- 如果使用 lodash 将属性存在于另一个对象中,则向对象添加属性
- 调整窗口大小时,可拖动的对象会出现在容器外部
- 如何使用javascript从主svg对象动态创建svg视图框
- 如何使用json将对象列表从java转换为javascript
- 序列化数据属性中对象的最可靠方法
- 如何访问声音管理器2创建的声音对象
- 警告 - 全局 THIS 对象的危险使用
- Google 闭包编译器中的“全局此对象的危险使用”警告
- 将__proto__分配给一个接口,将其变成一个对象——聪明或危险
- 重写JavaScript对象和函数的危险
- 在JavaScript中为Google闭包编译器注释单例对象,或者“危险地使用全局this对象”.警告