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
(下面)。
但请注意,在你所引用的代码中,没有self
variables的原因。 您可以使用原型函数(效率更高),而不是为每个实例创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 Xyz
expression式完成,并且未初始化的对象作为expression式的结果返回。 出于这个原因,我从上面删除了try/catch
。 -
我build议不要依靠自动分号插入的恐怖。 使用分号结束expression式(包括将函数分配给variables或属性时)。