ключевое слово "this" внутри закрытия - PullRequest
2 голосов
/ 07 октября 2010

Я видел кучу примеров, но не могу заставить какой-то пример кода работать.

Возьмите следующий код:

var test = (function(){
    var t = "test";
    return {
        alertT: function(){ 
            alert(t);
        }
    }
}());

и у меня есть функция для window.load вроде:

test.alertT();

Это все отлично работает. Однако, когда я пытаюсь явно установить контекст t внутри alert () в alertT , я просто получаю undefined.

Я пробовал:

var that = this;
alert(that.t); //undefined

Я пробовал:

        return {
            that: this,
            alertT: function(){ 
                alert(that.t); // undefined!
            }
        }

и я попробовал:

var test = (function(){
    var t = "test";
    var myObj = this;
    return {
        alertT: function(){ 
            alert(myObj.t); // undefined!
        }
    }
}());

что мне не хватает? Мне нужно иметь возможность явно задавать контекст для таких вещей, как обратные вызовы и т. Д. Я тоже видел примеры (/280601/javascript-closures-i-eto), что похоже на то, что я делаю, так почему же это не работает?

Ответы [ 3 ]

1 голос
/ 07 октября 2010

t - это обычная переменная в области действия внешней анонимной функции (и, следовательно, также внутренней анонимной функции).Это не свойство объекта, поэтому вы просто устанавливаете его без ссылки на this, that или the_other.

var test = (function(){
    var t = "test";
    return {
        alertT: function(){ 
            alert(t);
        },
        setT: function (new_value) {
            t = new_value;
        }
    }
}());
test.alertT();
test.setT('hello, world');
test.alertT();

Синтаксис, который вы используете - это обычный шаблон длясоздание чего-то, что действует как приватная переменная в JS.

1 голос
/ 07 октября 2010

т не входит в сферу применения «это». t является локальной переменной метода. Так что где-то нужно сделать

this.t = whatever

...

вот реальный пример из приложения, которое я пишу

var scope = this;

cells.forEach(function(cell, index) {
            var given = cell.get('given');

            var value = cell.get('value'),
                            valueAsString = '%@'.fmt(value);


             var rowValues = scope.getRowForIndex(index);
            ...
}

область действия внутри функции forEach - это область действия массива 'ячейки', по которому я итерирую. Поскольку я хочу что-то делать в области вызова, я использую замыкание ...

0 голосов
/ 07 октября 2010

В C # и Java можно сделать что-то вроде этого:

public class MyClass {
    private int x;

    public void DoSomething(int x) {
        int a = this.x;
        int b = x;
    }
}

Переменные a и b будут иметь значения из разных x, поскольку один - это класс x, а один - методы x.

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

public class MyClass {
    private int classX;

    public void DoSomething(int x) {
        int a = classX;
        int b = x;
    }
}

То, что у вас ситуация с JavaScript, в значительной степени.По крайней мере, в ситуации, которую вы описываете.Используя методы apply и call, вы можете изменить контекст, в котором выполняется функция, но вы никогда не сможете различить переменные с одинаковыми именами, но с разными областями действия.Для этого вам просто придется использовать разные имена.

...