Вопрос об объекте / функции Javascript - PullRequest
1 голос
/ 08 февраля 2010

У меня есть экземпляр класса ведения журнала "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

Можете ли вы объяснить, в чем моя ошибка?

Ответы [ 3 ]

7 голосов
/ 08 февраля 2010

Когда вы назначаете функцию 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); }
4 голосов
/ 08 февраля 2010

в отличие от некоторых других языков, «this» в 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!
1 голос
/ 08 февраля 2010

Я думаю, что проблема может быть в том, что this.logf работает в области видимости объекта runner, а не в logger. Если ваша функция logger.log вообще использует «this», она будет использовать бегунок вместо регистратора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...