Ответ 1
Одна из причин заключается в том, что с минимализацией me
может стать намного короче this
.
Я нахожу этот шаблон по всему исходному коду 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;
},
Одна из причин заключается в том, что с минимализацией me
может стать намного короче this
.
Если ваша библиотека делает это в тех местах, где нет встроенных закрытий/обратных вызовов, которые могут иметь собственное значение 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 set to window)
// but, we can access "self" here
self.style.display = "none"; // make button disappear 2 seconds after it was clicked
}, 2000);
};
Помимо причин стиля и причин исключения, я решил посмотреть на производительность, чтобы увидеть, было ли this
или self
быстрее. Я создал этот тест jsperf.
Насколько я могу судить, в какой-либо из современных браузеров, которые я пробовал, или даже IE6, с использованием this
по сравнению с использованием локальной переменной, например self
или me
, практически нет разницы в производительности. Chrome всегда немного быстрее с self
, а другие слишком близки к вызову. Я думаю, что мы можем исключить любые из соображений производительности. Вот скриншот из результатов, которые я увидел:
Выполняется иногда, чтобы поддерживать область в закрытии, но в основном (как в опубликованном примере), чтобы разрешить минимизацию, поскольку me
может быть уменьшена до одного символа, а this
не может быть изменена. После приблизительно 3 или 4 использования this
в заданной функции это становится важным (меньше этого, и на самом деле у вас может быть несколько дополнительных байтов из дополнительного кода объявления). Это так просто - это не имеет ничего общего с стилем программирования или прихотью.
Проблема, скорее всего, связана с функциями закрытия, например, в качестве аргумента при регистрации обратного вызова. В этом случае "this" может иметь совершенно другое значение, поэтому вместо этого нужно использовать "я".
Основываясь на примере Ext.panel.Panel
, который вы только что добавили, если мое понимание переменных Javascript не является неправильным, не приведение здесь здесь никакого значения не повлияет на то, что делает код.
Единственная возможная возможность - стиль.
Хотя я бы назвал это переоценкой, это полезно в той мере, что если вы когда-либо хотели добавить обратный вызов, который требовал доступа к this
в этом контексте, вам не нужно было возвращаться, чтобы изменить все this
до me
. В конце концов, печатать :s/
сложно.
На самом деле, хотя это, вероятно, не мотивация, то для стиля это имеет смысл. Многие соглашения о стиле заключаются в том, чтобы усложнить что-то забыть, например, всегда помещать {} вокруг блока else, даже если это один оператор. Переназначение "this" будет иметь аналогичный аффект в этом начале. У программистов JavaScript были бы закрытия "просто работы" более высокого процента времени.
За пределами сохранения контекста для использования в закрытии я не знаю никакой программной разницы с использованием этого шаблона. Возможно, это просто соглашение, используемое ExtJS.
Кроме того, как отметил Даниэль, возможно, еще больше сократить код во время минимизации. Библиотеки, такие как ExtJS, jQuery и т.д., Много заботятся о размерах файлов, и использование этой технологии может обеспечить достаточную экономию размера файла.
например. 1000 'this', при условии, что 1 char= 1 байт, составляет 4kb. Используя вышеприведенную технику, возможно, сбрить 2 или 3 kb.
обновление: Продвинулся вперед и сделал небольшой эксперимент.
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' используется повторно в блочных областях вашего кода).
Для рамки ExtJS.
У ExtJS есть свои механизмы для обработки проблемной области Javascript, минимизация - это только причина для var me = this
.
Более подробную информацию по этому вопросу можно найти в этой теме форума Sencha.
Во время работы с ExtJs я не нашел это соглашение полезным. Я не часто использовал закрытие. При работе в других рамках, таких как AngularJs, эта конвенция спасла меня от боли и страданий. Недостаток вашей области - трудоемкая ошибка для отслеживания. Как только я начал использовать это соглашение, я снова не ошибался.