Ответ 1
this
в JavaScript очень особенный и мощный. Это может означать что угодно. Я описываю некоторые из них здесь и здесь, но это действительно стоит найти хороший учебник по JavaScript и провести некоторое время с ним.
Посмотрите сначала на использование jQuery, затем поговорите об этом в общем в JavaScript (немного).
В jQuery, в частности
В коде, написанном с помощью jQuery, this
обычно ссылается на элемент DOM, который является объектом вызываемой функции (например, в обратном вызове).
Пример обратного вызова события jQuery (что this
находится в .bind
docs):
$("div").click(function() {
// Here, `this` will be the DOM element for the div that was clicked,
// so you could (for instance) set its foreground color:
this.style.color = "red";
// You'll frequently see $(this) used to wrap a jQuery object around the
// element, because jQuery makes lots of things a lot simpler. You might
// hide the element, for example:
$(this).hide();
});
Аналогично, различные функции jQuery, которые действуют на все элементы, соответствующие текущему селектору jQuery, могут, при желании, принимать функцию, и когда эта функция вызывается, this
снова является элементом DOM в вопросе — например, функция html
позволяет это:
// Find all divs inside the `foo` element, and set
// their content to their CSS class name(s)
// (Okay, so it a hokey example)
$("#foo div").html(function() {
return this.className;
});
Другое место, в котором jQuery использует this
, находится в обратном вызове jQuery.each
:
var a = ["one", "two", "three"];
jQuery.each(a, function() {
alert(this);
});
..., который будет предупреждать "один", затем "два", затем "три". Как вы можете видеть, это совершенно другое использование this
.
(Смутно, jQuery имеет две функции, называемые each
, одну выше, которая находится непосредственно в самой функции jQuery/$и всегда называется таким образом [jQuery.each(...)
или $.each(...)
], а другая - в экземплярах jQuery [ объекты], а не jQuery/$function iself. Вот документы для другого, я не обсуждаю другой в этом ответе потому что он использует this
таким же образом html
и обратный вызов события, и я хотел показать другое использование this
jQuery.)
Обычно в JavaScript
Обновление. Что касается строгого режима ES5, это больше не верно, this
относится к объекту.this
может иметь любое значение. Значение this
в пределах любого заданного вызова функции определяется тем, как вызывается функция (а не там, где определена функция, как в таких языках, как С# или Java). Наиболее распространенный способ настройки this
при вызове функции - вызов функции через свойство объекта:
var obj = {};
obj.foo = function() {
alert(this.firstName);
};
obj.firstName = "Fred";
obj.foo(); // alerts "Fred"
Там, поскольку мы вызвали foo
через свойство на obj
, this
было установлено на obj
на время вызова. Но не создавайте впечатление, что foo
никоим образом не женат на obj
, это отлично работает:
var obj = {};
obj.foo = function() {
alert(this.firstName);
};
obj.firstName = "Fred";
obj.foo(); // alerts "Fred"
var differentObj = {};
differentObj.firstName = "Barney";
differentObj.bar = obj.foo; // Not *calling* it, just getting a reference to it
differentObj.bar(); // alerts "Barney"
Фактически, foo
не привязан вообще к какому-либо объекту вообще:
var f = obj.foo; // Not *calling* it, just getting a reference to it
f(); // Probably alerts "undefined"
Там, поскольку мы не вызывали f
через свойство объекта, this
не был явно установлен. Если this
явно не задано, по умолчанию используется глобальный объект (который находится в window
в браузерах). window
, вероятно, не имеет свойства firstName
, и поэтому мы получили "undefined" в нашем предупреждении.
Существуют другие способы вызова функций и установка того, что this
: с помощью функций .call
и .apply
:
function foo(arg1, arg2) {
alert(this.firstName);
alert(arg1);
alert(arg2);
}
var obj = {firstName: "Wilma"};
foo.call(obj, 42, 27); // alerts "Wilma", "42", and "27"
call
устанавливает this
в первый аргумент, который вы ему даете, а затем передает любые другие аргументы, которые вы передаете ему вызывающей функции.
apply
делает то же самое, но вы даете ему аргументы для функции как массива, а не отдельно:
var obj = {firstName: "Wilma"};
var a = [42, 27];
foo.apply(obj, a); // alerts "Wilma", "42", and "27"
// ^-- Note this is one argument, an array of arguments for `foo`
Опять же, есть гораздо больше, чтобы исследовать this
в JavaScript. Концепция является мощной, немного обманчивой, если вы привыкли к тому, как это делают некоторые другие языки (а не если вы привыкли к некоторым другим), и стоит знать.
Вот несколько примеров this
, не относящихся к объекту в строгом режиме ES5:
(function() {
"use strict"; // Strict mode
test("direct");
test.call(5, "with 5");
test.call(true, "with true");
test.call("hi", "with 'hi'");
function test(msg) {
console.log("[Strict] " + msg + "; typeof this = " + typeof this);
}
})();
Вывод:
[Strict] direct; typeof this = undefined [Strict] with 5; typeof this = number [Strict] with true; typeof this = boolean [Strict] with 'hi'; typeof this = string
Если в свободном режиме все из них сказали бы typeof this = object
; живая копия.