2013-12-19 4 views
0

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

window.Think = { 
    initialize: function(){ 
     this.currentNumber = 0; 
    }, 
    updateNumber: function(){ 
     this.currentNumber += 1; 
    }, 
    listener: function(){ 
     document.getElementById('foo').addEventListener('click', function(){ 
     this.parent.updateNumber(); //this is where I want to call the prev function 
    } 
} 

Ошибка я получаю Cannot call method 'updateNumber' of undefined

Как я могу позвонить Think.updateNumber() изнутри listener()?

+1

Нет, 'this' не ссылается на' window.Think' внутри обратного вызова прослушивателя событий. Кроме того, FYI, у вас есть синтаксическая ошибка (отсутствует '});' в конце метода 'listener', перед вторым до последнего"} ") – jraede

+0

В его коде' this.parent.updateNumber (); 'находится в функции для события' click' на '# foo', поэтому' this' ссылается на этот элемент (если я не ошибаюсь), а не 'window.Think' – jraede

+2

Это, люди, есть почему отступы важны. Из-за отсутствия надлежащего отступа, он был полностью упущен, была функция вложенного обратного вызова. –

ответ

5

Функции обратного вызова часто теряют контекст (контекст - это значение this). Таким образом, вы должны сохранить значение this. к локальной переменной, которая совместно используется функцией обратного вызова. Общим соглашением для этого является var self = this.

listener: function(){ 
    var self = this; 
    document.getElementById('foo').addEventListener('click', function(){ 
     self.updateNumber(); 
    } 
} 
+1

Если вы открыты для CoffeeScript, у него есть встроенные функции для ссылки на 'this' родительской функции. Вы определяете функцию с '->' и функцию, которая сохраняет предыдущее значение 'this' с' => '. Оказывает эту проблему спорный. – jraede

+1

Одна из лучших функций CoffeeScript, но этот вопрос не касается CoffeeScript. –

+0

@jraede: функции стрелок ES6 ведут себя одинаково. –

3

this будет отскок определения области function «ы. Решение создает другую переменную можно сослаться this на:

listener: function(){ 
    var that = this; 
    document.getElementById('foo').addEventListener('click', function(){ 
     that.updateNumber(); 
    }); 
} 

В зависимости от того, что браузеры вы ориентируетесь bind также может быть решение:

listener: function(){ 
    document.getElementById('foo').addEventListener('click', function(){ 
     this.updateNumber(); 
    }.bind(this)); 
} 
+0

+1 'bind' - это способ пойти :) – thefourtheye

+0

@TimWolla' this' не имеет ничего общего с областью видимости, она задается тем, как вызывается функция, или 'bind'. – RobG

2

Проблема заключается в том, что ключевое слово «это» представлять.

listener: function(){//We call this is function one. 
     document.getElementById('foo').addEventListener('click', function(){//function two 
     this.parent.updateNumber(); //this is where I want to call the prev function 
    } 

В функции одного, «это» представляет объект Think.In функции два, «этот» представляет элемент foo.so, если вы хотите, чтобы вызвать метод updateNumber, вы должны получить ссылку на объект Think.We просто сохраните «это» функции один в переменной, например:

listener: function(){//We call this is function one. 
     var outerThis=this;//save Think here. 
     document.getElementById('foo').addEventListener('click', function(){//function two 
     outerThis.updateNumber();//use Think.updateNumber here. 
    } 

Теперь мы выполняем проделанную работу. Потому что в javascript функция может получить доступ к своей переменной внешней функции, поэтому мы можем использовать externalThis во второй функции.

+0

+1 для хорошего объяснения, которое неправильно использует «область» или «контекст». – RobG

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