2010-02-07 96 views
1

我有一个日志记录类“记录器”的实例,这个类有一个函数“日志(txt)”,它的作品。Javascript对象/函数问题

现在我声明了一个不同的类“Runner”,并将其传递给构造函数中的记录器实例。一切正常,直到第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 

你能解释一下什么是我的错?

回答

4

其它语言不同,“本”在javascript是动态的,也就是说,“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! 
+0

'function.bind'不仅仅是一个框架功能,它是下一个版本的ECMA262-5的标准方法。因此,您不应该将它检入到函数原型中,而不检查它是否已经存在,并且您放在那里的任何方法都应该支持标准'bind'方法的全部功能。这个不处理参数传递。见例如。 http://stackoverflow.com/questions/1558065/access-event-object-in-event-handler/1558289#1558289的完整实现的底部。 – bobince 2010-02-07 22:42:10

1

我认为问题可能是this.logf运行在runner对象的范围内,而不是logger。如果你的logger.log函数完全使用“this”,它将使用runner而不是logger。

7

当您将log函数分配给当前对象的logf成员时,它将成为当前对象的成员函数。当你调用的时候,函数内部的this对象将引用它的新对象,而不是this.logger了。因此,该函数将不会找到其他要在记录器对象上调用的函数的变量。

为了避免这种情况,你可以写一个简单的函数转发给Logger对象:

this.log = function() { return this.logger.log(arguments); } 

或者,使用封闭:

var obj = this.logger; 
this.log = function() { return obj.log(arguments); } 
+0

阅读你的答案几个后次我相信我明白。另一个问题就是:第四行我能做些什么?记录器对象(也传递给其他类的实例,请参见第12行)是否会受到损害或更改? – user89021 2010-02-07 21:47:55

+1

@ user89021:'this.logger'将简单地引用原始的'logger'对象,并不会以任何方式“伤害”它。虽然方法需要知道它们属于哪个对象,但对象不关心它们是否被另一个对象包含。 – sth 2010-02-07 22:18:13