Понимание ключевого слова "this"
В этом коммите есть изменение, которое я не могу объяснить
deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );
становится
deferred.done( arguments ).fail( arguments );
AFAIK, когда вы вызываете функцию как член некоторого объекта типа obj.func()
, внутри функции this
привязан к obj
, поэтому не нужно использовать функцию через apply()
только для привязки this
к obj
. Вместо этого, согласно комментариям, это было необходимо из-за предшествующей реализации $.Callbacks.add
.
Я сомневаюсь не в jQuery, а в самом языке Javascript: когда вы вызываете функцию типа obj.func()
, как это может быть внутри func()
ключевое слово this
не связано до obj
?
Ответы
Ответ 1
Мое сомнение касается не jQuery, а языка Javascript self: когда вы вызываете функцию, подобную obj.func(), как это может быть внутри func() это ключевое слово не связано с obj?
Ну, единственный способ, которым это возможно, - это если obj.func
ссылается на функцию bound
, тогда не имеет значения, как вы назови это. В этом случае не имеет значения, как вы вызываете эту функцию, независимо от того, выполняете ли вы obj.func()
, func()
, func.call({})
, func.apply({})
. Я не уверен, как это связано с этим сообщением.
Чтобы уточнить, я отвечаю на цитируемый вопрос, который интерпретируется как:
Учитывая такую сигнатуру вызова, как: obj.func()
, как возможно, что this
не obj
внутри вызываемой функции для вызова?
Ответ 2
В то время как другие ответы касаются вашего вопроса о ключевом слове this
, они не отвечают на ваш вопрос о том, почему используется apply
. Здесь кикер: apply
не используется для установки ключевого слова this
в этом примере. Вместо этого он используется для передачи arguments
в качестве аргументов функций done
и fail
.
Возьмем этот пример:
var x = {
a: function(a1, a2, a3) {
console.log(a1, a2, a3);
}
}
function callA() {
x.a.apply(x, arguments);
x.a(arguments);
}
callA('red', 'blue', 'green');
Если вы выполните этот код, вы увидите разницу между x.a.apply(x, arguments);
и x.a(arguments);
. В первом случае a1
, a2
и a3
соответствуют цветам "красный", "синий" и "зеленый". Во втором случае a1
представляет собой объект типа массива [ "red", "blue", "green" ]
и a2
и a3
undefined
.
Аналогично, в вашем опубликованном примере apply
используется для правильного передачи объекта arguments
, а не для установки ключевого слова this
.
Ответ 3
Это возможно только путем ссылки на функцию из другого объекта таким образом
obj2.func = obj.func;
obj2.func(); // 'this' now refers to obj2
var func2 = obj.func;
func2(); // 'this' now refers to the global window object
или путем вызова .apply() или .call() для привязки this
к любому произвольному объекту.
Ответ 4
Функция всегда вызывается с приемником, называемым this
внутри функции, которая предоставляется при вызове.
Когда вы пишете
obj.someFunc = function() {...
вы не говорите, что someFunc должен иметь в качестве получателя obj, вы просто говорите, что obj имеет свойство someFunc, значение которого является функцией.
Если вы делаете
var aFunc = obj.someFunc;
как это делается во многих местах (например, обратный вызов), и после этого
aFunc();
приемник (this
) в этом случае является окном.
Это потому, что функции в javascript, в отличие от таких языков, как java, являются объектами "первого класса", что означает, в частности, что вы можете передавать их как значения и не привязаны к уникальному предустановленному получателю.
Ответ 5
Сокращенная версия, которую я использую, заключается в том, что this
в JavaScript всегда относится к объекту, в котором выполняющаяся в данный момент функция является методом, за исключением особого случая, когда метод является обратным вызовом, когда this
ссылается на объект, к которому привязан обратный вызов (например, кнопка).
Изменить: обратите внимание, что глобальная функция похожа на метод объекта window
.
Эта страница QuirksMode помогла мне, когда я узнал об этом.