Javascript 具有正确的值';这';在JS中
我有两个Javascript“对象”类似于Javascript 具有正确的值';这';在JS中,javascript,this,Javascript,This,我有两个Javascript“对象”类似于 var Object2 = new (function() { this.FetchData = function(callback) { // do some stuff callback(data); }; }); var Object1 = new (function() { this.DisplayStuff = function() { }; this.LoadD
var Object2 = new (function() {
this.FetchData = function(callback) {
// do some stuff
callback(data);
};
});
var Object1 = new (function() {
this.DisplayStuff = function() {
};
this.LoadData = function() {
Object2.FetchData(this.OnData);
};
this.OnData = function(data) {
// this == window
this.DisplayStuff(); // doesn't work
};
});
当Object1接收到对OnData的回调时,“this”的值设置为window是否有任何方法可以绕过此问题,使OnData中的“this”值成为Object1的实例而不是窗口?基本解决方案是使用
apply
强制回调上下文。(或调用
。区别在于参数的传递方式。数组或“正常”)请参阅文档。对于回调,您必须使用“this”作为窗口(通常)。但是,您可以向Object1中添加一个指向自身的成员(很多时候它的get调用是“self”,即“var self=this;”),然后使用该成员,即self.DisplayStuff()。简单的方法是在变量中存储对此的引用,然后使用以下方法:
如果你做了很多,你可能想考虑在EcMAScript第五版的函数原型上使用.bDUE()方法。此方法可在以下不受支持的情况下实施:
// From Prototype.js
if (!Function.prototype.bind) { // check if native implementation available
Function.prototype.bind = function(){
var fn = this, args = Array.prototype.slice.call(arguments),
object = args.shift();
return function(){
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
};
};
}
以及生成的函数调用:
this.LoadData = function() {
Object2.FetchData(this.OnData.bind(this));
};
框架中常用的一种技术是让调用方决定回调函数的
上下文应该是什么。因此,FetchData
函数看起来像(感谢@Andy告诉我上下文为null或未定义时的默认范围-它是全局对象)
调用FetchData
时,传递Object1
作为回调的上下文
Object2.FetchData(this.OnData, this);
另一个选项是使用将OnData
函数与Object1
绑定
“this”的模糊性对于javascript来说真的很烦人。所以我尽量避免说“这个”。我是这样做的:
var Object2 = (function() { // no need for a "new" keyword any more
var self = {}; // instead of the auto-supplied "this", create my own "self"
self.FetchData = function(callback) {
// do some stuff
callback(data);
};
return self; // don't forget to return "self"
});
var Object1 = (function() {
var self = {}; // instead of the auto-supplied "this", create my own "self"
self.DisplayStuff = function() {
};
self.LoadData = function() {
Object2.FetchData(this.OnData);
};
self.OnData = function(data) {
self.DisplayStuff();
};
return self; // don't forget to return "self"
});
你失去了使用Object.prototype的能力使用这种技术,你就失去了使用“instanceof”进行测试的能力,但你永远不必考虑“this”是什么 谁叫Object1.OnData?你把它附在一个活动上了吗?你能告诉我你是如何把它附加到一个事件上的吗?对象2在哪里调用对象1?回调是对象2上的方法之一吗?我希望我能选择两个答案。这是一个很好的响应。不需要上下文| |窗口
,如果上下文未定义或为空,它将默认为全局对象,在网页的情况下是窗口。@Andy-感谢您为我们指出未指定上下文的默认行为。谢谢@T.斯通-很高兴你喜欢它的舔!像这样的事情正是我所希望的。为什么不让自己这么做呢?这样你就不会失去这些能力了。这也很好。我想我开始这样做是因为我对“这件事”感到愤怒,并且对驱逐它的想法感到兴奋。事实上,这不是真的。我一直在试验Crockford的“寄生遗传”方法,它避开了“这个”。
Object2.FetchData(this.OnData, this);
Object2.FetchData(this.onData.bind(this));
var Object2 = (function() { // no need for a "new" keyword any more
var self = {}; // instead of the auto-supplied "this", create my own "self"
self.FetchData = function(callback) {
// do some stuff
callback(data);
};
return self; // don't forget to return "self"
});
var Object1 = (function() {
var self = {}; // instead of the auto-supplied "this", create my own "self"
self.DisplayStuff = function() {
};
self.LoadData = function() {
Object2.FetchData(this.OnData);
};
self.OnData = function(data) {
self.DisplayStuff();
};
return self; // don't forget to return "self"
});