2010-10-07 2 views
2

Я видел кучу примеров, но, похоже, не могу получить пример кода.«this» ключевое слово внутри закрытия

Возьмем следующий код:

var test = (function(){ 
    var t = "test"; 
    return { 
     alertT: function(){ 
      alert(t); 
     } 
    } 
}()); 

и у меня есть функция на window.load как:

test.alertT(); 

Это все работает отлично. Однако, когда я пытаюсь явно установить контекст t внутри alert() в alertT, я просто получаю undefined.

Я пробовал:

var that = this; 
alert(that.t); //undefined 

Я пробовал:

 return { 
      that: this, 
      alertT: function(){ 
       alert(that.t); // undefined! 
      } 
     } 

и я попытался:

var test = (function(){ 
    var t = "test"; 
    var myObj = this; 
    return { 
     alertT: function(){ 
      alert(myObj.t); // undefined! 
     } 
    } 
}()); 

что мне не хватает? Мне нужно иметь возможность устанавливать контекст явно для таких вещей, как обратные вызовы и т. Д. Я тоже видел примеры (http://stackoverflow.com/questions/346015/javascript-closures-and-this-context), которые кажутся такими, какие я делаю, так почему это не работает?

+0

Почему вы хотите явно указать контекст? Ваши примеры на самом деле не показывают этого. Либо вам придется передать контекст в alertT-функцию, либо вам придется использовать метод bind для привязки функции к контексту вашего выбора. – Jakob

+0

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

ответ

1

t - это просто нормальная переменная в области внешней анонимной функции (и, следовательно, также анонимная функция). Это не свойство объекта, поэтому вы просто устанавливаете его без ссылки на this, that или the_other.

var test = (function(){ 
    var t = "test"; 
    return { 
     alertT: function(){ 
      alert(t); 
     }, 
     setT: function (new_value) { 
      t = new_value; 
     } 
    } 
}()); 
test.alertT(); 
test.setT('hello, world'); 
test.alertT(); 

Синтаксис, который вы используете, является обычным шаблоном для создания чего-то, что действует как частная переменная в JS.

+0

Я не мог понять, что спрашивал статичиппо, пока не увидел ваш ответ. Я предполагаю, что он думал, что «это» было ссылкой на область, содержащую переменные замыкания? Хорошее объяснение. Мой совет - не использовать «это», если вы не пишете код типа «класс», где «это» относится к манипулируемому объекту, к которому этот пример можно легко изменить. Но, как вы упомянули, этот модуль patttern дает вам действительно частные переменные (что затрудняет отладку) –

1

t не входит в сферу применения «это». t - переменная, локальная для метода. Так что где-то, что нужно сделать

this.t = whatever 

...

вот реальный пример жизни из приложения я пишу

var scope = this; 

cells.forEach(function(cell, index) { 
      var given = cell.get('given'); 

      var value = cell.get('value'), 
          valueAsString = '%@'.fmt(value); 


      var rowValues = scope.getRowForIndex(index); 
      ... 
} 

в сфере внутри функции Foreach является сфера действия массив «ячеек», над которыми я повторяюсь. Поскольку я хочу делать что-то в области вызова, я использую закрытие ...

+0

Правда. Но это может быть и плохая идея. Если «this» является глобальным объектом в этом методе, будет создана глобальная переменная. – Jakob

+0

, но поскольку это замыкание, если я просто ссылаюсь на t, я получаю замкнутый элемент t, потому что сама функция не содержит никакой переменной t. Мне действительно интересно узнать, как я могу явно ссылаться на замкнутый элемент t внутри метода. – hackerhasid

+0

@jakob, совершенно. Кажется, что OP просто пытается понять, как работает область действия в закрытии, и это всего лишь пример – hvgotcodes

0

В C# и Java, можно сделать что-то вроде этого:

public class MyClass { 
    private int x; 

    public void DoSomething(int x) { 
     int a = this.x; 
     int b = x; 
    } 
} 

Переменные а и Ь будут иметь значения от различных х годов, так как один класс-х х один является методы х.

Теперь представьте, если вы не можете использовать this, чтобы явно ссылаться на x класса. Тогда вам нужно будет сделать следующее:

public class MyClass { 
    private int classX; 

    public void DoSomething(int x) { 
     int a = classX; 
     int b = x; 
    } 
} 

Это я, ситуация у вас в JavaScript, в значительной степени.По крайней мере, в ситуации, которую вы описываете. Используя методы apply и call, вы можете изменить контекст, в котором выполняется функция, но вы никогда не сможете отличить переменные с именами имен, но разными областями. Для этого вам просто нужно использовать разные имена.

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