Javascript / NodeJS:通过对象似乎覆盖“自我” – closures问题?

我的第一个Stackoverflow问题(我记得)。 经过多年的实践,我正在慢慢地重新开发开发Node和Javascript。

我希望这真的很简单,但我不明白我做错了什么。

我有一个相当简单的JavaScript对象的2个实例。 当我把这个对象的一个​​实例传递给另一个函数的时候,它会掉下来。

  • 我第一次提到一个“自我”的价值很好。

  • 然后我调用传入的对象上的函数。

  • 如果我以后再尝试引用“自我”,看起来“自我”被传入的对象覆盖了。

这是对象来源:

"use strict"; //simple object module.exports.SimpleObject = function SimpleObject(inputName) { try{ var self = this; //closure so we don't lose this reference in callbacks self.name = inputName; } catch(err) { console.log('Unable to create SimpleObject: '+err); } SimpleObject.prototype.getName = function() { self = this; return self.name; } SimpleObject.prototype.nestedOverwrite = function(anObject) { self = this; return "#1 self.name: "+self.name+" ObjectName: "+anObject.getName()+" #2 self.name: "+self.name; } return this; } 

这里是testing用例:

 var testSimpleObjectModule = require('./simpleObject'); var o0 = new testSimpleObjectModule.SimpleObject('test0'); var o1 = new testSimpleObjectModule.SimpleObject('test1'); console.log(o0.nestedOverwrite(o1)); console.log(o1.nestedOverwrite(o0)); 

这是我得到的输出:

 #1 self.name: test0 ObjectName: test1 #2 self.name: test1 #1 self.name: test1 ObjectName: test0 #2 self.name: test0 

希望你能看到在每种情况下,第一个调用self.name是好的,第二个失去了上下文。

任何帮助非常感谢!

每次调用构造函数时,都会将原型对象分配给新的SimpleObject 。 所以第二次调用构造函数时,原型会被更新,并且使用原型创build的任何以前的对象都会使用函数(使用新的self值)开始。

如果你想要这些封闭的self ,不要把它们放在原型上,把它们放在this (下面)。

但请注意,在你所引用的代码中,没有selfvariables的原因。 您可以使用原型函数(效率更高),而不是为每个实例创build函数。 要做到这一点,使用this (不分配给self ),并在构造函数之外定义函数,如下所示:

 "use strict"; //simple object module.exports.SimpleObject = function SimpleObject(inputName) { this.name = inputName; }; SimpleObject.prototype.getName = function() { return this.name; }; SimpleObject.prototype.nestedOverwrite = function(anObject) { return "#1 this.name: "+this.name+" ObjectName: "+anObject.getName()+" #2 this.name: "+this.name; }; 

但是,如果你正在做一些self事情,那么你并没有显示出来,这意味着你真的需要它(例如,当函数被称为&mdasdh时,你不能相信这个值;它们被用作callback/事件处理程序等),这是你如何做到这一点:

 "use strict"; //simple object module.exports.SimpleObject = function SimpleObject(inputName) { var self = this; self.name = inputName; self.getName = function() { return self.name; }; self.nestedOverwrite = function(anObject) { return "#1 self.name: "+self.name+" ObjectName: "+anObject.getName()+" #2 self.name: "+self.name; }; }; 

边注:

  • 没有理由在构造函数结束时return this

  • 请注意,我们不想做self = this; 在每个function中; 使用self在于,当函数被调用时,你不想依赖this具有正确值的东西。 (如果yoU可以依赖this被设置的话,那么使用函数的原型版本。)

  • 永远不要在构造函数中捕获exception,只是说你不能做构造,因为通过这样做,你允许new Xyzexpression式完成,并且未初始化的对象作为expression式的结果返回。 出于这个原因,我从上面删除了try/catch

  • 我build议不要依靠自动分号插入的恐怖。 使用分号结束expression式(包括将函数分配给variables或属性时)。