我使用多个原型来管理一些复杂的情况,但我在使用"this"时遇到了问题。我不能100%确定如何描述,因为我不熟悉正确的术语,但我会尝试的。
函数X有一个指向函数Y内函数的变量。函数Y内的这个方法希望访问函数Y范围内的变量,但当我使用它时,它指的是函数X。
我已经创建了一个带有示例的JSFiddle,使用原型等等(因为这是我所处的场景)。然而,代码很短,所以我将在下面包含它:
var Abc = function(options) {
alert('2');
options = options || {};
this.myVar = options.myVar || 'Abc.myVar';
};
Abc.prototype = {
onEvent: function() {
alert('myVar: ' + this.myVar);
}
};
var Xyz = function(options) {
alert('3');
options = options || {};
this.listenFn = options.listenFn || function() {
alert('x');
};
this.myVar = options.myVar || 'Xyz.myVar';
};
Xyz.prototype = {
execute: function() {
alert('4');
this.listenFn();
}
};
$(document).ready(function(){
alert('1');
var a = new Abc();
var x = new Xyz({listenFn: a.onEvent});
x.execute();
});
我已经按照代码执行的顺序设置了警报。因此:
- 是文档准备就绪的开始
- 是Abc实例的创建
- 是Xyz实例的创建,其中Abc实例的onEvent函数被分配给Xyz的listenFn
- 位于调用Zyz上的execute的点内,该点依次调用Xyz的onEvent,并显示this.myVar的值
我遇到的问题是,当在Abc上的方法内部时,"this"指的是Xyz实例。我需要能够为Xyz的实例设置/获取myVar的值。我怀疑我可能会在创建一个传递到新Xyz语句中的函数时做一些混乱的事情,从而将Abc的实例传递回自己,但不幸的是,这在我正在处理的情况下是不可能的(也不是很优雅)。
干杯。
编辑
这是你的问题的答案
$(document).ready(function(){
alert('1');
var a = new Abc();
var x = new Xyz({listenFn: a.onEvent.bind(a) }); // <------- bind
x.execute();
});
像这样使用bind会将a.onEvent内部的this
值预设为a
。请注意,IE8不支持bind
,但您可以从这里轻松添加垫片。
另一种方法是说:
$(document).ready(function(){
alert('1');
var a = new Abc();
var x = new Xyz({listenFn: function() { a.onEvent() });
x.execute();
});
在不深入研究代码的情况下,我只想说:在JavaScript中计算this
的值非常容易;这完全取决于函数被调用的方式。
如果你有
x.foo()
,那么,无论什么*,this
都将等于foo内部的x
。如果您有
foo()
,那么,无论*是什么,this
都将是全局对象,或者在foo内部的严格模式下未定义。如果说
new foo()
,那么this
将是一个新对象,其原型将设置为foo.prototype
如果你说
foo.call(a)
,那么在foo内部this
将是a
*,但这在这里并不适用。
*一个例外是,如果您已将foo声明为
var foo = function() { }.bind(obj);
那么对于foo的所有调用,您已经将this
预先绑定为obj
,并将覆盖上面的规则。