Javascript 闭包编译器未对此应用@const

Javascript 闭包编译器未对此应用@const,javascript,google-closure-compiler,Javascript,Google Closure Compiler,我正在尝试让这段代码正常工作: /** @constructor */ function Foo() { /** @const */ this.bar = 5; // edit: does now work // this.bar = 3; } var f = new Foo(); // should be inlined (like other constants) alert(f.bar); 我已经尝试添加更多注释(类型、构造函数),@enum而不是@

我正在尝试让这段代码正常工作:

/** @constructor */
function Foo()
{
    /** @const */
    this.bar = 5;

    // edit: does now work
    // this.bar = 3;
}

var f = new Foo();

// should be inlined (like other constants)
alert(f.bar);
我已经尝试添加更多注释(类型、构造函数),
@enum
而不是
@const
(对于
this.bar
),
me=this
,所有这些都没有任何效果

在这方面,专家们并没有真正的帮助

有什么办法可以让它工作吗?
如果没有,原因是什么?

添加
/**@constructor*/
有效:

/** @constructor */
function Foo()
{
    /** @const */ 
    this.bar = 5;

    // cc does not complain
    //this.bar = 3;
}

var f = new Foo();

// should be inlined
alert(f.bar);
汇编至:

alert((new function() { this.a = 5 }).a);
如果我取消注释
this.bar=3我收到了预期的警告:

JSC_CONSTANT_PROPERTY_REASSIGNED_VALUE: constant property bar assigned a value more than once at line 9 character 0
this.bar = 3;
^

文件中说:

如果标记为@const的变量多次赋值,编译器将生成警告<代码>如果变量是对象,请注意编译器不禁止更改对象的属性。

附言: 您是否在脚本或HTML页面中包含以下代码

  <script src="closure-library/closure/goog/base.js"></script>

编译器没有任何通用的“内联属性”逻辑。您可以使用prototype函数在高级模式下将其内联:

/** @constructor */
function Foo() {}
Foo.prototype.bar = function() { return 5 };

var f = new Foo();
alert(f.bar());
将编译为:

alert(5);

如果方法“bar”只有一个定义,并且“bar”仅在调用表达式中使用,编译器将执行此操作。在一般情况下,用于此操作的逻辑是不正确的(如果调用的对象没有定义调用将抛出的“bar”)。然而,它被认为是“足够安全的”。

它仍然不能像其他常量那样内联
f.bar
。这应该会输出
警报(5)
。好吧,这听起来像是坏消息,+1感谢您的帮助。仍然在寻找一种破解方法。你引用的文本说你仍然可以更改常量对象的属性。但是,可以将对象的属性标记为常量(另请参见stewe的响应)。我正试图让它与
新的
操作员一起工作。另外,我在脚本中不使用闭包库。闭包编译器在没有它的情况下工作得非常好。当以
@const
注释作为前缀时,闭包编译器将内联一个变量(称为),这对于正常的
var
状态非常有效。这就是我试图用属性重现的行为。它确实与您描述的过程有关。正如我所说,编译器不支持这一点。它会在可能的情况下检查类属性上的@const注释,但在执行优化时,它对实际使用这些信息更为保守;似乎没有办法做到这一点。无论如何,我现在正在使用cpp。