我有一个日志类“logger”的实例,这个类有一个函数“log(txt)”,它可以工作。
现在我声明了一个不同的类“Runner”,并将它传递给构造函数中的logger实例。一切都可以工作到第5行,但是第7行没有写入日志:
var Runner = function (logger) {
// constructor:
logger.log("this way it works");
this.logger = logger; //line 4
this.logger.log("this also works"); //line 5
this.logf = this.logger.log; //create a shorthand for logging
this.logf("this is not written to log. why? i thought i can create a var for a function"); //line 7
};
var logger = new Logger(); //class not shown here
var runner = new Runner(logger);
var otherinstancce = new OtherClass(logger) //line 12
你能解释一下我的错误吗?
答案 0 :(得分:7)
将log
函数分配给当前对象的logf
成员时,它将成为当前对象的成员函数。当你调用is时,函数内部的this
对象将引用它的新对象,而不再引用this.logger
。因此,该函数将找不到要在记录器对象上调用的其他函数的变量。
为避免这种情况,您可以编写一个转发到记录器对象的简单函数:
this.log = function() { return this.logger.log(arguments); }
或者,使用闭包:
var obj = this.logger;
this.log = function() { return obj.log(arguments); }
答案 1 :(得分:4)
与其他语言不同,javascript中的“this”是动态的,也就是说,“this”是调用函数的上下文,而不是定义的位置。
function Foo() {
this.x = 1;
this.func = function() { alert(this.x) }
}
foo = new Foo
foo.func() // works
var copy = foo.func
copy() // nope, because func() lost its context
要在函数及其上下文之间创建耦合,您必须在闭包中“锁定”上下文。大多数框架以bind()方式为此提供糖,简化形式,看起来像这样
Function.prototype.bind = function(o) {
var p = this;
return function() { p.apply(o) }
}
具有锁定上下文功能分配的按预期工作
bar = foo.func.bind(foo)
bar() // yes!
答案 2 :(得分:1)
我认为问题可能是this.logf在runner对象的范围内运行而不是logger。如果你的logger.log函数完全使用“this”,它将使用跑步者而不是记录器。