Почему это закрытие не имеет доступа к 'этому' ключевому слову? - jQuery

Я - новичок к закрытиям (и Javscript в целом), и я не могу найти удовлетворительное объяснение относительно того, что продолжается в этом коде:

function myObject(){
    this.myHello = "hello";
    this.myMethod = do_stuff;
}

function do_stuff(){
    var myThis = this;
    $.get('http://example.com', function(){
        alert(this.myHello);
        alert(myThis.myHello);
    });
}

var obj = new myObject;
obj.myMethod();

Это предупредит 'неопределенный' и затем 'привет'. Очевидно, это не должно быть конкретным jQuery, но это - самая простая форма моего исходного кода, который я мог придумать. Закрытие в do_stuff() имеет доступ к переменным в том объеме, но по-видимому это правило не относится this ключевое слово.

Вопросы:

Что происходит с this когда закрытие передается вне объема do_stuff() (в этом случае $.get())? Делает myThis содержите копию this или ссылка на него? Разве это обычно - не хорошая идея использовать this в закрытиях?

Любой ответ очень ценится.

14
задан thewiglaf 23 July 2010 в 23:59
поделиться

3 ответа

Что с этим происходит, когда закрытие передается за пределы do_stuff () (в данном случае $ .get ()) ?

Каждая функция имеет свой собственный контекст выполнения, ключевое слово this извлекает значение текущего контекста.

Идентификатор doStuff и свойство obj.myMethod относятся к одному и тому же объекту функции, но поскольку вы вызываете его как свойство объекта ( obj.myMethod (); ), значение this внутри этой функции будет ссылаться на obj .

После успешного выполнения запроса Ajax jQuery вызовет вторую функцию (запуск нового контекста выполнения) и будет использовать объект, содержащий настройки, используемые для запроса, в качестве значения this этого Перезвони.

Содержит ли myThis его копию или ссылку на него?

Идентификатор myThis будет содержать ссылку на объект, на который также ссылается это значение во внешней области.

Разве это обычно не является хорошей идеей использовать это в замыканиях?

Если вы понимаете, как значение this обрабатывается неявно, я не вижу никаких проблем ...

Поскольку вы используете jQuery, вы можете проверить метод jQuery.proxy , это служебный метод, который можно использовать для сохранения контекста функции, например:

function myObject(){
    this.myHello = "hello";
    this.myMethod = do_stuff;
}

function do_stuff(){
    $.get('http://example.com', jQuery.proxy(function(){
        alert(this.myHello);
    }, this)); // we are binding the outer this value as the this value inside
}

var obj = new myObject;
obj.myMethod();

См. также:

10
ответ дан 1 December 2019 в 14:31
поделиться
$.get('http://example.com', function(){
    alert(this.myHello);  // this is scoped to the function
    alert(myThis.myHello);  // myThis is 'closed-in'; defined outside
});

обратите внимание на анонимную функцию. это в той области видимости функции. myThis внешней области видимости, в которой был определен myHello. Проверьте это в firebug.

«this» всегда относится к текущему объему выполнения, я полагаю. Если вы хотите взять текущую область видимости и сохранить ее, вы делаете то, что делали, а именно присваиваете ее другой переменной.

2
ответ дан 1 December 2019 в 14:31
поделиться
$.get('http://example.com', function(){
   // inside jQuery ajax functions - this == the options used for the ajax call
});

Что происходит с этим, когда закрытие передается вне области действия do_stuff() (в данном случае $.get())?

С ним ничего не "происходит", this по-прежнему остается this для этого закрытия, контекст выполнения функций, вызываемых из закрытия, не наследуется автоматически this.

Содержит ли myThis копию this или ссылку на него?

В JavaScript все нескалярные присваивания являются ссылками. Таким образом, это ссылка на this, если вы измените свойства любого из них, они изменятся для обоих.

Обычно не стоит использовать this в замыканиях?

Обычно не стоит использовать this в замыканиях, но если вы собираетесь использовать замыкания внутри, которым нужен доступ к тому же this, хорошей практикой будет сделать именно то, что вы сделали: var someName = this; и затем получить доступ, используя someName

1
ответ дан 1 December 2019 в 14:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: