#javascript #closures
#javascript #замыкания
Вопрос:
Я использую этот фрагмент в Javascript примерно 100 раз в день, чтобы закрыть заключающий объект:
Class.prototype.Method = function(arg){
var Ta = this;
var e = function(){
Ta.doSomething(arg);
};
};
есть ли способ избежать переменной Ta и по-прежнему ссылаться на «внешний» (это слово правильное?) объект?
Ответ №1:
Я не знаю, стал бы я отстаивать это как превосходство, но вы могли бы использовать «.bind ()»:
var e = function() {
this.doSomething(arg);
}.bind(this);
Это гарантирует, что this
значение внутри функции «e» всегда будет this
значением окружающего контекста. Эта .bind()
функция доступна в более новых браузерах или через полизаполнение, подобное тому, что есть на сайте MDC.
Мне скорее нравится сохранять эти локальные переменные, особенно в сложных функциях, которые настраивают обработчики событий и тому подобное; это помогает прояснить взаимосвязи между уровнями кода.
Ответ №2:
a) Вы могли бы продолжить использовать этот подход с более значимыми именами переменных. Использование that
является общепринятым соглашением — это указывает на то, что ваша переменная является просто другим значением «this», но для другой области действия функции.
б) Вы можете использовать утилиту привязки функции. Некоторые библиотеки JavaScript поставляются с ним. Или вы можете просто создать свой собственный:
function bind(fn, scope) {
return function () {
fn.apply(scope, arguments);
};
}
// for your example:
Class.prototype.Method = function(arg) {
var e = bind(function() {
this.doSomething(arg);
}, this);
};
// Alternatively, extend the Function prototype (may raise some eyebrows):
Function.prototype.bind = function (scope) {
var fn = this;
return function () {
fn.apply(scope, arguments);
};
};
// for your example:
Class.prototype.Method = function(arg) {
var e = function() {
this.doSomething(arg);
}.bind(this);
};
Обновить:
Как отметил @Pointy, bind
на самом деле это часть новой версии спецификации JavaScript, которую уже используют современные браузеры: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
Комментарии:
1. Даже если бы я искал что-то более простое, меня заинтересовало это расширение объекта Function. Спасибо за публикацию!
Ответ №3:
Я не верю, что есть. Я все время делаю одно и то же.
Ответ №4:
Я использую небольшой самодельный фреймворк, чтобы легко использовать наследование прототипов, и в этом фреймворке у меня примерно такой же фрагмент кода. Я думаю, что без этого никак не обойтись.
Теперь вопрос: почему бы этого не сделать? считаете ли вы, что это плохая практика, и почему?
Фрагмент кода, который я использую :
function getCallback(obj, methodName) {
var method = obj[methodName];
function callback() {
if (obj[methodName] === callback) {
return method.apply(obj, arguments);
}
return obj[methodName].apply(obj, arguments);
}
return callback;
}