Каково значение var me = this; - PullRequest
       1

Каково значение var me = this;

31 голосов
/ 15 сентября 2011

Я нахожу этот шаблон по всему исходному коду ExtJS.

method: function() {
  var me = this;
  ...
  me.someOtherMethod();
}

Почему они просто не используют this? Есть ли какое-то преимущество у всегда , часто определяющего me (за исключением того, что нет необходимости вводить 2 символа)? Я могу понять, пытаются ли они поддерживать контекст с помощью замыкания, но это делается там, где вообще нет замыкания.

Пример из Ext.panel.Panel:

disable: function(silent) {
    var me = this;

    if (me.rendered) {
        me.el.addCls(me.disabledCls);
        me.el.dom.disabled = true;
        me.onDisable();
    }

    me.disabled = true;

    if (silent !== true) {
        me.fireEvent('disable', me);
    }

    return me;
},

Ответы [ 10 ]

38 голосов
/ 15 сентября 2011

Если ваша библиотека делает это в местах, где нет встроенных замыканий / обратных вызовов, которые могут иметь свое собственное значение this, то это просто "практика", "стиль" или "соглашение", которые они решили следуйте их методам. Нет НИКАКОЙ причины программирования, чтобы всегда это делать.

В конкретном примере кодирования, который вы сейчас добавили в свой вопрос, нет никаких причин, о которых я знаю, кроме общего стиля кодирования. Этот код будет генерировать тот же результат в немного меньшем коде:

disable: function(silent) {

    if (this.rendered) {
        this.el.addCls(this.disabledCls);
        this.el.dom.disabled = true;
        this.onDisable();
    }

    this.disabled = true;

    if (silent !== true) {
        this.fireEvent('disable', this);
    }

    return this;
},

Когда используется обратный вызов или замыкание, это часто делается потому, что внутри метода используются обратные вызовы, где они все еще хотят ссылку на this, но эти обратные вызовы будут иметь свое собственное значение this, поэтому присваиваем:

var me = this;

или чаще в другом коде, который я видел:

var self = this;

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

Вот общий пример:

document.getElementById("myButton").onclick = function () {
    var self = this;       // save reference to button object use later
    setTimeout(function() {
        // "this" is not set to the button inside this callback function (it's set to window)
        // but, we can access "self" here 
        self.style.display = "none";    // make button disappear 2 seconds after it was clicked
    }, 2000);
};
24 голосов
/ 15 сентября 2011

Одна причина в том, что при минимизации me может стать намного короче, чем this.

14 голосов
/ 16 сентября 2011

Помимо стилей и причин минимизации, я решил посмотреть на производительность, чтобы узнать, был ли this или self быстрее. Я создал этот jsperf test .

Насколько я могу судить, практически нет разницы в производительности ни в одном из современных браузеров, которые я пробовал, или даже в IE6 между использованием this и использованием локальной переменной, такой как self или me. Chrome немного быстрее с self, а остальные слишком близко, чтобы звонить. Я думаю, что мы можем исключить любые причины производительности. Вот скриншот результатов, которые я видел:

enter image description here

4 голосов
/ 16 сентября 2011

Иногда это делается для поддержания контекста в замыкании, но в основном (как в опубликованном примере) для минимизации, поскольку me может быть уменьшено до одного символа, тогда как this не может быть изменено.Приблизительно после 3 или 4 использования this в данной функции это становится важным (меньше этого, и вы могли бы фактически получить несколько дополнительных байтов из дополнительного кода объявления).Это так просто - это не имеет ничего общего со стилем программирования или прихотью.

4 голосов
/ 15 сентября 2011

Скорее всего, проблема связана с функциями закрытия, например, в качестве аргумента при регистрации обратного вызова. В этом случае «this» может иметь совершенно другое значение, поэтому вместо него нужно использовать «me».

2 голосов
/ 16 сентября 2011

На самом деле, хотя это, вероятно, не мотивация, делать это для стиля имеет некоторый смысл. Множество стилевых соглашений заключаются в том, чтобы усложнить забывание чего-либо, например, всегда помещать {} вокруг блока else, даже если это один оператор. Переназначение «this» будет иметь аналогичный эффект в том смысле, что начинающие программисты JavaScript будут иметь замыкания «просто работают» в более высоком процентном соотношении времени.

2 голосов
/ 16 сентября 2011

Исходя из только что добавленного вами примера Ext.panel.Panel, если мое понимание переменных Javascript не является совершенно неверным, то отсутствие выполнения присваивания здесь не окажет абсолютно никакого влияния на то, что делает код.

Единственная оставшаяся возможностьэто стиль.

Хотя я бы назвал это сверхинжинирингом, полезно, если вы когда-нибудь захотите добавить колбэк, который требует доступа к this в этом контексте, вам не нужно идтивернуться, чтобы изменить все this на me.В конце концов, набрать :s/ сложно.

1 голос
/ 02 марта 2014

Во время работы с ExtJ я не счел это соглашение полезным. Я не использовал закрытие очень часто. При работе в других средах, таких как AngularJs, это соглашение спасло меня от боли и страданий. Неправильное определение объема является трудоемкой ошибкой для отслеживания. Как только я начал использовать это соглашение, я больше никогда не ошибся в объеме.

1 голос
/ 08 августа 2012

Специально для среды ExtJS.

ExtJS имеет свои собственные механизмы для обработки проблемных областей видимости Javascript, минимизация только причина для выполнения var me = this.

Более подробная информация по теме этой ветки форума Sencha .

1 голос
/ 16 сентября 2011

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

Кроме того, как отметил Дэниел, возможно, код будет сокращен еще больше во время минимизации. Такие библиотеки, как ExtJS, jQuery и т. Д., Очень заботятся о размерах файлов, и использование этого метода может привести к достаточной экономии размера файла

например. 1000 'this' при условии, что 1 символ = 1 байт, составляет 4 КБ. Использование техники, описанной выше, может сбрить 2 или 3 килобайта.

обновление: Ушли вперед и провели небольшой эксперимент ..

var test = {
  a : function() {
     this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
  },
  b : function() {
      this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
  },
  c : function() {
      this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
  }
}

преобразуется в

var test={a:function(){this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x=""},b:function(){this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x=""},c:function(){this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x=""}}

, а

var test = {
  a : function() {
     var me=this;
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
  },
  b : function() {
      var me=this;
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
  },
  c : function() {
      var me=this;
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
  }
}

превращается в

var test={a:function(){var a=this;a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x=""},b:function(){var a=this;a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x=""},c:function(){var a=this;a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x=""}}

, что переводит примерно на 10% больше или меньше символов (конечно, это зависит от того, сколько «this» используется многократно в объемах блока вашего кода).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...