Closure编译器编号在高级优化中未定义

时间:2012-07-06 07:09:39

标签: google-closure-compiler

我有以下代码行

frame = self.spriteData['backgroundps.png'];
self.bgBoard  = new gg.casino.game.sprite(self.spriteSheet, frame, 0, 0, frame.w, frame.h);
console.log(frame);
console.log(self.bgBoard.x + ' ' + self.bgBoard.y + ' ' + self.bgBoard.w + ' ' + self.bgBoard.h);

和gg.casino.game.sprite定义为

gg.casino.game.sprite = function(sheet, frame, x, y, twidth, theight) {
    this.sheetRef                               =   sheet;
    this.frame                                  =   frame;
    this.x                                      =   x;  
    this.y                                      =   y;  
    this.w                                      =   twidth;
    this.h                                      =   theight;
    console.log(this.x + ' ' + this.y + ' ' + this.w + ' ' + this.h);
}

使用simpleoptimization进行编译时,一切运行良好,我得到以下日志:

0 0 800 480
(frame object)
0 0 800 480

但是当我使用高级优化编译时,日志显示

0 0 undefined undefined 
(frame object) - with correct values
0 0 undefined undefined 

这段代码出了什么问题?

修改

frame = self.spriteData['backgroundps.png'];

之后添加了一个日志
console.log('ps ' + frame.w + '   ' + frame.h);

并打印w和h为undefined !!!!!!

ps undefined undefined

其中,console.log(frame)在下一行中打印具有正确值的对象

编辑2:

更多关于self.spriteData: 我有一个从texturepacker导出的json文件。它有一个对象数组,每个对象表示为

{
"filename": "backgroundps.png",
"frame": {"x":105,"y":304,"w":800,"h":480},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":800,"h":480},
"sourceSize": {"w":800,"h":480}
}

我遍历那个json数组并将值分配给self.spriteData,如下所示:

    var respData                            =   xhr.getResponseJson();
    self.spriteData                         =   {};
    for(var i = 0, len = respData.frames.length; i < len; i++) {
        self.spriteData[respData.frames[i].filename] = respData.frames[i].frame;
    }

所以frame将具有以下结构,该结构将在控制台上打印:

Object
  h: 480
  w: 800
  x: 105
  y: 304

所以在高级编译中,如果我将frame打印为console.log(frame),则没有问题。但是当我尝试访问其成员console.log(frame.h)时,它会打印为undefined。刚尝试将@expose注释添加到var frame = {};,希望它不会重命名,但没有帮助。

修改frame分配更改为     frame.x = self.spriteData ['backgroundps.png']。x;     frame.y = self.spriteData ['backgroundps.png']。y;     frame.w = self.spriteData ['backgroundps.png']。w;     frame.h = self.spriteData ['backgroundps.png']。h;

并声明frame.wframe.h注释`@type {number}(对于x和y没做,因为它们已经正常工作)。

现在console.log(框架)显示

Object
  a: undefined
  b: undefined
  x: 105
  y: 304

但为什么?

编辑(已解决):D :-) 我明确地将frame的成员声明为

/**
 * @type {number}
 * @expose
 */
frame.w                                     =   0;

/**
 * @type {number}
 * @expose
 */
frame.h                                     =   0;

/**
 * @type {number}
 * @expose
 */
frame.x                                     =   0;

/**
 * @type {number}
 * @expose
 */
frame.y                                     =   0;

现在可行: - )

感谢Kayhr,Ross和Chad的帮助。但现在我想知道我应该在正确答案中找到答案吗?

2 个答案:

答案 0 :(得分:1)

self.spriteData ['backgroundps.png']的定义是什么?

我愿意打赌self.spriteData ['backgroundps.png']的'w'和'h'键是用字符串定义的。如果是这样,当你使用dot-syntax访问这些属性时,事情通常会中断,因为编译器会保持字符串不变,但优化用点语法编写的属性的名称。

例如:

  foo['bar'] => a['bar']
  foo.bar    => a.b

...其中a和b是假设的编译器输出标记。

请参阅:https://developers.google.com/closure/compiler/docs/api-tutorial3#propnames

答案 1 :(得分:1)

无法重现它。我用简单的对象伪造了丢失的代码,以使代码运行。输出是相同的,如果我使用SIMPLE或ADVANCED优化无关紧要。我想你的问题出现在这里你没有提到的代码中(可能在这个spriteData的定义中)。请给我们一个完整的示例和您使用的确切编译器选项。

这是我正在编译的代码,也许你可以看到你的REAL代码的重要区别:

// Faked code (The stuff you didn't include in the question):

var gg, self;
gg = {};
gg.casino = {};
gg.casino.game = {};
self = { spriteData: { 'backgroundps.png': { w: 800, h: 480 } } };

// Your code (unchanged):

gg.casino.game.sprite = function(sheet, frame, x, y, twidth, theight) {
    this.sheetRef                               =   sheet;
    this.frame                                  =   frame;
    this.x                                      =   x;  
    this.y                                      =   y;  
    this.w                                      =   twidth;
    this.h                                      =   theight;
    console.log(this.x + ' ' + this.y + ' ' + this.w + ' ' + this.h);
}

frame = self.spriteData['backgroundps.png'];
self.bgBoard  = new gg.casino.game.sprite(self.spriteSheet, frame, 0, 0,  frame.w, frame.h);
console.log(frame);
console.log(self.bgBoard.x + ' ' + self.bgBoard.y + ' ' + self.bgBoard.w +  ' ' + self.bgBoard.h);