2012-01-11 3 views
3

У меня есть функция:найти родительский объект функции обратного вызова

myObject.myFunction = function(callback){ 
    callback(); 
} 

и обратный вызов

randomObject.callBack = function(){ 
    console.log(this); 
} 

, если я позвоню randomObject.callBack() непосредственно, я получаю родительский объект в консоли. Однако, если я звоню myObject.myFunction(randomObject.callBack), он регистрирует элемент DOM.

Как получить доступ к родительскому объекту?


Примечание

Я не знаю имя функции обратного вызова родительского объекта перед выполнением.

ответ

5

Контекст (т.е. значение this) объекта определяется во время выполнения функции, не в момент его определения. Передача randomObject.callBack другой функции не отправляет контекст (бит randomObject); он просто отправляет эту функцию.

Предположительно контекст устанавливается, когда myFunction называет его. Поскольку вы явно не предоставляете контекст (например, с call или apply), контекст будет window.

Вы можете изменить это, явно указав, каков должен быть контекст функции перед ее запуском. Вы можете сделать это с помощью метода bind:

myObject.myFunction(randomObject.callBack.bind(randomObject)) 

Теперь, когда вы звоните callback внутри myFunction, randomObject будут регистрироваться.

Отметьте, что bind относительно новый; не все браузеры поддерживают его. На странице MDN, с которой я связан выше, есть немного кода, который заставит его работать во всех браузерах.

+0

Что делать, если я не знаю имя randomObject на момент написания, мне нужно установить его во время выполнения? –

+0

@MildFuzz Я не понимаю, как это могло произойти ... – lonesomeday

+0

Итак, код является гибким, ему не нужно переписывать, потому что я создал новый экземпляр объекта. –

1

Это происходит потому, что при вызове функции без объекта, внутри функции this будет указывать на Window object.To избежать этого мы обычно делаем, как этот

myObject.myFunction = function(callback){ 
    callback(); 
} 


randomObject.callBack = function(){ 
    console.log(this); 
} 

function proxyCallback(){ 
    randomObject.callBack(); 
} 

myObject.myFunction(proxyCallback); 
1

В JavaScript this относится к контексту объекта в которой функция называется. Это не обязательно связано с каким-либо объектом, на котором он был установлен .

Вы можете думать об этом так, как будто функции не определены как члены объектов, а называются членами объектов.

В зависимости от контекста может быть разрешено использование this.

  1. Созданный объект, если вызову функции предшествовало новое ключевое слово.
  2. Объект слева от точки при вызове функции.
  3. Глобальный объект (как правило, окно), если ни одно из указанных выше не предусмотрено.
  4. Первый аргумент, предоставленный функции call или apply.

В вашей ситуации, что-то подобное может быть целесообразным:

myObject.myFunction(function(){randomObject.callBack()}); 

Это создает замыкание, так что в myFunction, callback называется членом randomObject.

+1

Вы забыли о том, как '.bind' перезаписывает все правила. – Raynos

+0

@Raynos IIRC,' .bind' - это просто функция, которая создает замыкание типа в моем примере. В зависимости от того, как это реализовано, оно будет соответствовать моим правилам 2 или 4. Я не прав? –

+0

'var o = {}; o.foo = f.bind (null); o.foo(); // this === null'. '.bind' жестко связан. 'F.bind (нуль) .call ({}); // this === null'. Вы не можете отменить эту привязку. – Raynos

Смежные вопросы