Javascript / NodeJS:传入对象似乎覆盖了"self"-关闭问题
Javascript / NodeJS : Passed in object seems to overwrite "self" - closure issue?
我的第一个Stackoverflow问题(我记得)。在缺席多年并尝试了Node和Javascript之后,我正在慢慢地回到开发中。
我希望这真的很简单,但我就是看不出我做错了什么。
我有一个相当简单的javascript对象的两个实例。当我将该对象的一个实例传递给函数时,其他的东西就失效了。
-
我第一次引用"self"值,它很好
-
然后在传入的对象上调用一个函数。
-
如果我尝试之后再次引用"self",似乎"self"已被传入的对象覆盖。
对象来源:
"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;
}
下面是测试用例:
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
的原型对象。因此,第二次调用构造函数时,原型被更新,并且之前使用原型创建的任何对象都开始使用new函数(具有新的self
值)。
如果你想让这些闭包有self
,不要把它们放在原型上,把它们放在this
上(后面有更多)。
但是请注意,在您引用的代码中,没有理由使用 但是如果你对self
变量。您可以使用原型函数(这更有效),而不是为每个实例创建函数。为此,使用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
做了一些你没有显示的事情,这意味着你真的需要它(例如,当函数被调用时,你不能信任this
的值 &mdasdh;它们被用作回调/事件处理程序等),您可以这样做:"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;
;使用self
的全部意义在于,当调用函数时,您不希望依赖于this
具有正确的值。(如果你可以依靠this
被设置,那么使用函数的原型版本) -
永远不要在构造函数中捕获异常,然后说你不能进行构造,因为这样做,你允许
new Xyz
表达式完成,并且未初始化的对象作为表达式的结果返回。出于这个原因,我已经从上面删除了try/catch
。 -
我推荐而不是依赖于自动分号插入的恐惧。以分号结束表达式(包括将函数赋值给变量或属性时)
- 铬:“;未捕获的语法错误:意外的标记:"
- 可以设置“;文件名"发生错误时显示的内联脚本标记的
- JS表单提交"无法使用Chrome数据保护程序加载此页面.尝试重新加载页面.调试信息:POST CISmtuK
- 检测电话窃听,即:<a href="电话:xxx">在UIWebview上
- 使用“+="操作人员
- //而不是在src=“”上使用http://"属性
- "未捕获的语法错误:意外的标记}"
- 可以<脚本类型=“;text/javascript”>window.location=“/"</
- "实例范围”;TypeScript类的getter/setter
- Javascript复选框函数:;缺少:在属性id之后"
- "“;变量未引用正确的对象
- "日期“;AJAX请求返回的类型值未定义
- 得到"TypeError:无法读取属性'filename'未定义的“;调用“npm start
- Soundcloud api"未捕获的类型错误:无法读取属性'uri'“未定义”;
- "工具提示"jQuery插件坏了
- "锻造;React中的表达式
- 图像可以从源<img src=""/>.TEXT可以在没有javascript的情况下从外部
- 如何提取“;href"最近列表项中的属性值
- CKEditor如何允许href="javascript:void(0)"在小部件中
- 没有内联脚本,仍然得到"由于内容安全策略指令而被拒绝:“;脚本src'self'&”;