2013-05-06 3 views
3

Я спутал себя в следующем случае:Как «это» ищется в обратном вызове Javascript

function foo() { 
} 

foo.prototype.bar1 = function() { 
    console.log(this); // shows "Window"!! 
} 

foo.prototype.bar2 = function(func) { 
    func(); 
} 

var f = new foo(); 
f.bar2(f.bar1); 

Как/почему бы результат console.log (это) есть «окно»? Я думал, что независимо от того, как вы называете публичную функцию класса здесь, «это» всегда должно ссылаться на «foo».

А также, что такое правильный способ избежать такого рода ошибок?

Благодаря

+0

правила не отличаются от любого другого вызова функции (см Http: //stackoverflow.com/questions/16382165/why-do-i-lose-the-context-of-this-in-javascript). Функция Function.prototype.bind (или эмуляция) может быть здесь полезной, как и общие закрытия. – user2246674

+0

Вы можете использовать 'func.apply (this)' для получения ожидаемого поведения, я думаю. –

+0

'func.call (this)' должен делать. – elclanrs

ответ

1

Когда вы f.bar2(f.bar1), вы передаете ссылку на BAR1 в BAR2; внутри bar2, он известен только как «func», и связь с f теряется. The value of this is determined dynamically when the function is invoked. Если вы вызываете f.bar1(), это будет f, но когда вы вызываете func(), он не определен и возвращается к глобальному объекту (окну).

У меня explained this earlier следующим образом:

Основные правила, это будет глобальный объект, если:

  • функция не вызывается как метод объекта (тогда это будет объект) или
  • функция вызывается как конструктор с новым оператором (в этом случае это будет указывать на то, что новый объект имеет )

Один из способов избежать этого является создание связанного функции и передать, что:

f.bar2(f.bar1.bind(f)); 

Обратите внимание, что Function.prototype.bind не поддерживается старыми браузерами, так что вам может понадобиться polyfill (есть один доступный на MDN).

В простом сценарии вы представлены, вы можете делать то, что elclanrs предлагает в своем комментарии, как цель это не доступно внутри bar2:

func.call(this); 
Смежные вопросы