开发者

Javascript Object / Function Question

I have an instance of a logging class "logger", this class has a function "log(txt)", which works.

Now I am declaring a different class "Runner" and I pass it the logger instance in the constructor. Everything works until line 5, but line 7 does not write to the log:

var Runner = function (logger) {
  // constructor:
  logger.log("this way it works");
  this.logger = logger; //line 4
  this.logger.l开发者_开发问答og("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

Can you explain what is my mistake?


When you assign the log function to the logf member of the current object it becomes a member function of this current object. When you call is, the this object inside of the function will refer to it's new object, not to this.logger anymore. Therefore the function will not find variables other functions it wants to call on the logger object.

To avoid this, you can write a simple function that forwards to the logger object:

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

Or, using a closure:

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


unlike some other languages, "this" in javascript is dynamic, that is, "this" is the context in which the function was called, not where is was defined.

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

to create coupling between function and its context you have to "lock" the context in a closure. Most frameworks provide a sugar for this in form of bind() method, which, in simplified form, looks like this

Function.prototype.bind = function(o) {
  var p = this;
  return function() { p.apply(o) }
}

with locked context function assignment works as expected

bar = foo.func.bind(foo)
bar() // yes!


I think the issue might be this.logf is running within the scope of the runner object as opposed to the logger. If your logger.log function uses "this" at all, it will be using the runner instead of the logger.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜