Помогите, «это» сбивает меня с толку в JavaScript - PullRequest
25 голосов
/ 27 января 2010

Работа с JavaScript одна из самых запутанных вещей при использовании this

var x = {  
  ele : 'test',
  init : function(){ 
    alert(this.ele);
  }
}

Однако при работе с несколькими объектами и особенно событиями контекст this изменяется и становится запутанным, чтобы отслеживать / понимать.

Так что, если у кого-то есть лучшие материалы / рекомендации / мысли / лучшие практики, пожалуйста, поделитесь. Также я хотел бы знать, если использование this дает какое-либо (производительность) преимущество или что?

Ответы [ 5 ]

27 голосов
/ 27 января 2010

Речь идет не о производительности, а о доступе к свойству определенного экземпляра объекта: -

x.init()

Не будет отображаться «тест», если вы не использовали this в функции.

По сути, вышеуказанная строка такая же, как: -

x.init.call(x);

первый параметр в использовании call присваивается this при выполнении функции.

Теперь рассмотрим: -

var fn = x.init;  //Note no () so the function itself is assigned to the variable fn
fn();

Теперь вы ничего не получаете в оповещении. Это потому, что вышеприведенное эффективно: -

fn.call(window);

В Javascript, размещенном в браузере, объект window является синонимом глобального объекта. Когда функция вызывается «в необработанном виде», this по умолчанию принимает глобальный объект.

Классическая ошибка делает что-то вроде этого: -

var x = {
   ele: 'test';
   init: function(elem) { 
      elem.onclick = function() { alert(this.ele); }
   }
}
x.init(document.getElementById('myButton'));

Однако это не работает, потому что функция, прикрепленная к событию onclick, вызывается браузером с использованием кода, подобного следующему: -

onclick.call(theDOMElement)

Следовательно, когда функция запущена, this не то, что вы думаете.

Мое обычное решение этой ситуации: -

var x = {
   ele: 'test';
   init: function(elem) {
      var self = this; 
      elem.onclick = function() { alert(self.ele); }
      elem = null;
   }
}
x.init(document.getElementById('myButton'));

Обратите внимание, что elem = null - это обходной путь утечки памяти в IE.

6 голосов
/ 27 января 2010

Это очень запутанно. Это зависит от того, как вы вызываете функцию. Даг Крокфорд написал хорошую статью в своей книге Javascript, Good Parts . Суть этого в этом превосходном ответе на иначе плохо сформулированный вопрос.

И нет, дело не в производительности.

3 голосов
/ 29 января 2010

Мне очень помогло следующее правило: каждый раз, когда вы видите this, думайте owner. Объект, которому принадлежит имя переменной, которой назначена функция, станет this. Если вы не можете понять, кому он принадлежит, то this будет окном.

2 голосов
/ 27 января 2010

Хорошая и поучительная статья о ключевом слове this: , (без каламбура). Статья может прояснить для вас вещи, я знаю, что это сделал для меня.

Основное правило заключается в том, что ключевое слово this внутри функции всегда относится к владельцу функции, а ключом к пониманию последствий является понимание того, когда функции ссылаются и когда они копируются . См. Вышеупомянутую статью для примеров.

1 голос
/ 27 января 2010

использование

var me = this;

за пределами

function(){

тогда вы можете обратиться ко мне внутри функции ()

...