Понятие «это» является одним из наиболее неправильно понятых аспектов JavaScript. Было много вопросов о StackOverflow, в которых обсуждается понятие «это», а также многочисленные посты в блогах, статьи и т. Д. Я не буду претендовать на звание эксперта, но я верю, что могу очистить некоторые мутные воды, очевидные в ваш вопрос.
Значение this зависит от контекста, в котором выполняется текущая функция. Рассмотрим следующий код:
this; // Alone, will be 'window' or DOMWindow
Теперь в контексте простого объекта:
var Klass = {
self: this // -> DOMWindow
}
Если бы мы исследовали Klass.self, мы обнаружили бы, что это все еще DOMWindow, а не фактически Klass. Это связано с тем, что значение this было оценено во время создания Klass и было создано на верхнем уровне в контексте DOMWindow.
Другой пример:
var Klass = {
func: function(){
console.log(this);
}
}
Klass.func(); // -> Klass
Теперь, если мы посмотрим на значение 'this' в результате выполнения Klass.func (), это фактически будет Klass. Это потому, что func был выполнен в рамках Klass. Другой пример:
var Klass = {
func: function(){
console.log(this);
}
}
var anotherFunc = Klass.func;
anotherFunc(); // -> this is now DOMWindow
anotherFunc - это ссылка на Klass.func, но не в контексте Klass. Мы просто использовали Klass, чтобы получить дескриптор func, но как только мы получили этот дескриптор, anotherFunc больше не имеет понятия о Klass. Это то же самое, что происходит с обработкой событий - часто вы передаете ее дескриптор функции, которую вы хотите выполнить. Как вы поняли, что ручка не имеет значения.
var Klass = {
func: function(){
console.log(this);
}
}
var anotherFunc = Klass.func;
anotherFunc.call(Klass); //-> this is now Klass again!
В приведенном выше примере мы выполняем anotherFunc с помощью функции 'call'. Это способ форсировать контекст выполнения. Если мы хотим передать аргументы функции, вы все равно можете сделать это:
anotherFunc.call(Klass, someArgument);
Есть много способов справиться с контекстом и «этим» в JavaScript. Приведенные выше примеры в основном касаются основных «объектов». Вы получаете еще несколько вариантов того, как обращаться с вещами, если ваш объект сам по себе является функцией. Но мы оставим это на время! Что касается вашего примера, вы можете получить желаемое поведение следующим образом:
var Klass = {
'name': 24,
'init': function() {
var input1 = document.getElementsByTagName('input')[0];
input1.addEventTrigger('change',Klass.func1,true); // note the addition of Klass to the func1 reference here. Because just 'func1' is undefined in the scope otherwise.
},
'func1': function( arg ) {
console.log(Klass.name );
if( arg instanceof Event ) {
arg.preventDefault();
}
}
}
РЕДАКТИРОВАТЬ: В ответ на ваш комментарий:
addEventTrigger('change',Klass.change.call(Klass),true)
Это вызовет Klass.change сразу, а не во время процесса обратного вызова. Вместо этого обратному вызову будет присвоен результат Klass.change, который не является вашим желаемым поведением. Вместо этого оберните его в анонимную функцию:
addEventTrigger('change', function(){
Klass.change();
}, true);
Обратите внимание, что мне не нужно использовать call () там, потому что я на самом деле выполняю его из Klass, предоставляя ему контекст выполнения Klass. Вы можете вызывать Klass.change () из любого места, и значение 'this' внутри change () будет Klass. Разница между непосредственным вызовом и использованием его для передачи дескриптора функции обратному вызову невелика, но просто помните, что «this» - это все, когда и как функция на самом деле получает выполненную , не назначенную или не переданную вокруг.
Google javascript на этом сайте: stackoverflow.com , где вы найдете множество других замечательных вопросов по этой теме, многие из которых включают отличные внешние ссылки.