Как я могу избежать использования этого фрагмента в Javascript closures?

#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;
}