Я - новичок к закрытиям (и 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
в закрытиях?
Любой ответ очень ценится.
Что с этим происходит, когда закрытие передается за пределы 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();
См. также:
$.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» всегда относится к текущему объему выполнения, я полагаю. Если вы хотите взять текущую область видимости и сохранить ее, вы делаете то, что делали, а именно присваиваете ее другой переменной.
$.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