Как я могу избежать использования этого фрагмента в замыканиях Javascript? - PullRequest
6 голосов
/ 14 июня 2011

Я использую этот фрагмент в Javascript примерно 100 раз в день, чтобы иметь замыкание на вмещающем объекте:

Class.prototype.Method = function(arg){
    var Ta = this;
    var e = function(){
        Ta.doSomething(arg);
    };
};

это способ избежать переменной Ta и по-прежнему ссылаться на "внешний" (это слово правильно?) объект?

Ответы [ 4 ]

3 голосов
/ 14 июня 2011

Я не знаю, что бы защищать это как превосходство, но вы могли бы использовать ".bind ()":

var e = function() {
  this.doSomething(arg);
}.bind(this);

Это гарантирует, что значение this внутри функции "e" всегда будет значением this окружающего контекста. Функция .bind() доступна в новых браузерах или через полифилл, такой как на сайте MDC.

Мне скорее нравится хранить эти локальные переменные, особенно в сложных функциях, которые устанавливают обработчики событий и тому подобное; это помогает прояснить отношения между слоями кода.

2 голосов
/ 14 июня 2011

а) Вы можете продолжить использовать этот подход с более значимыми именами переменных.Использование that является распространенным соглашением - оно указывает на то, что ваша переменная является просто еще одним значением "this", но для другой области действия функции.

b) Вы можете использовать утилиту связывания функций.Некоторые библиотеки 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

0 голосов
/ 14 июня 2011

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

Теперь вопрос: почему бы не сделать это? Как вы думаете, это плохая практика и почему?

Часть кода, который я использую:

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;
}
0 голосов
/ 14 июня 2011

Я не верю, что есть.Я все время делаю одно и то же.

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