当引用JavaScript的父对象时,如何避免“变量可能未被初始化”?

5

我知道有很多关于如何避免警告的问题,但是看起来我的问题是第一个特定于JavaScript的。在这种情况下,我想要在声明中引用我正在初始化的东西,就像这样:

var foo = new Foo({
  bar: new Bar({
    x: function(){
      doStuff(foo);
    }
  });
});

如果这看起来很熟悉,也许您以前使用过 ExtJS - 大多数内容都是如此构建的。

当我调用 foo.bar.x() 时,我想指向拥有 Bar (bar) 并调用函数 (x) 的 Foo (foo)。这可以工作,但我的 Eclipse 警告说“foo 可能未被初始化”,引用对 doStuff();的调用 - 因为当引擎首次查看该行时,我们还没有完成定义foo。当然,除非成功构建了 foo,否则无法调用 x(),但我的样式检查器显然尚未解决这个问题。

所以我不知道应该如何处理这个问题。我应该忽略这个警告吗?有没有办法将其标记为这样,这样我就不会再收到警告了?我做错了吗?我应该以不同的方式传递我的引用吗?


1
那是打错字了吗?应该是 doStuff(foo) 而不是 doStuff(f) - Duncan Smart
不要使用Eclipse。有更好的IDE(WebStorm 3)。 - Raynos
4个回答

2
var Foo = function() { }

var Bar = function (obj) {
  // foo is not initialized
  obj.x();
  // called doStuff with undefined
}

var foo = new Foo({
  bar: new Bar({
    x: function(){
      doStuff(foo);
    }
  });
});

Eclipse是正确的选择。如果你想要一个更好的分析系统,考虑使用WebStorm 3.0或Visual Studio 11作为你的JS IDE。


我明白为什么它在抱怨。我只是99%确定,在foo保持未定义的实际执行上下文中,x()是无法被调用的。是的,Bar构造函数将在Foo构造函数完成之前完成,但这并不意味着可以*对已创建(并分配给foo.bar)的 Bar对象进行任何操作,直到Foo对象完全构建完成,此时初始化了foo变量。如果这有任何意义... - Coderer
除了 Visual Studio(虽然我通常是它的粉丝...),因为我正在 Linux 上开发,所以它不是一个选项。我会认真看看 WebStorm - 感谢你的指引! - Coderer
@Coderer,这被称为在声明中不要引用自己。这样做是不好的实践(除非它是一个简单的声明,比如一个函数)。 - Raynos
好知道——是否有一种“正确”的方式来表达“给我一个引用到拥有我的对象”,就像我在原帖中描述的情况? - Coderer
@Coderer 示例。先创建对象,然后使用一个名字合适的链接方法来创建对象之间的链接。 - Raynos
显示剩余4条评论

1

这与JavaScript无关,但可能与Eclipse有关。变量foo可以在任何地方声明,因为变量声明在执行任何代码之前进行处理。它也可以在调用doStuff之前的任何时间进行初始化(尽管在不声明变量的情况下初始化变量被认为是不好的形式)。


0

我认为@RobG是对的,这是一个Eclipse的问题,最好就是处理它。但是如果你想避免这个问题,你可以在初始化之前声明foo,我敢打赌这样做会让Eclipse不再抱怨:

var foo;
foo = new Foo({
  bar: new Bar({
    x: function(){
      doStuff(foo);
    }
  });
});

仅仅声明是不够的(虽然已经声明,但技术上还没有“初始化”),我很难让自己做出像 var foo = "some garbage"; foo = new Foo(....); 这样的事情。 - Coderer
是的,你可以将其初始化为“null”,但此时你会破坏你的编码风格以适应你的IDE,这是不好的。 - nrabinowitz
Javascript不需要变量被赋值(初始化),所以这只是Eclipse挑剔而已。通过jslint运行您的代码,看看会得到什么! - RobG
我打算尝试JSLint,但它非常挑剔,修复所有警告可能需要我几个小时,所以我想先尝试在Eclipse中使用“宽松”的警告。我知道值不一定要初始化,但考虑到可能出现的问题(比如初始化代码在条件语句内部),思考这些问题也是有价值的。 - Coderer

0
首先,构造一个Foo。在它的构造函数中,传递了一个新的Bar,该Bar使用变量foo传递了一个函数。
但是,在Foo的构造函数完成之后才为foo分配一个值。此时,函数已经声明,使用未声明的变量foo。 如果该函数在Bar或Foo的构造函数中使用,它将失败。

首先,foo 被创建为局部变量对象的属性。由于代码似乎在全局作用域中,所以在执行任何代码之前它是全局对象的属性(全局变量)。当调用 doStuff 时,foo 存在,但可能尚未被分配一个值(即它可能是未定义的)。 - RobG
你是在暗示 OP 的代码会抛出错误吗?因为它不会。 - nrabinowitz
我并不是在建议,而是在解释为什么在调用doStuff时变量可能没有被赋值。我并不是说它一定会发生,但这种情况是有可能的,因此会发出警告。无论foo是声明为属性还是全局变量,在这种情况下都没有太大关系。最简单的方法是在调用此赋值之前给foo赋一个值(可以是null),以防止出现警告。 - GolezTrol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接