JQuery/JavaScript "this" путаница указателя

Поведение "this" при вызове функции bar меня озадачивает. См. Код ниже. Есть ли способ организовать "this" как простой старый экземпляр объекта js, когда bar вызывается из обработчика клика вместо того, чтобы быть элементом html?

// a class with a method

function foo() {

    this.bar();  // when called here, "this" is the foo instance

    var barf = this.bar;
    barf();   // when called here, "this" is the global object

    // when called from a click, "this" is the html element
    $("#thing").after($("<div>click me</div>").click(barf));
}

foo.prototype.bar = function() {
    alert(this);
}

Ответ 1

Добро пожаловать в мир javascript!: D

Вы зашли в область видимости и закрытия javascript.

За короткий ответ:

this.bar()

выполняется под действием foo (как это относится к foo)

var barf = this.bar;
barf();

выполняется под глобальной областью.

this.bar в основном означает:

выполните функцию, указанную в этом файле .bar, в рамках этого (foo). Когда вы скопировали this.bar в barf и запустили barf. Javascript понимается как, запустите функцию, обозначенную barf, и поскольку этого нет, она просто запускается в глобальной области.

Чтобы исправить это, вы можете изменить

barf();

примерно так:

barf.apply(this);

Это сообщает Javascript, чтобы связать область действия этого с barf перед ее выполнением.

Для событий jquery вам нужно будет использовать анонимную функцию или расширить функцию привязки в прототипе, чтобы поддерживать область видимости.

Для получения дополнительной информации:

Ответ 2

Хорошее объяснение ключевого слова this в JavaScript доступно на QuirksMode.

Ответ 4

Вы можете использовать Function.apply для функции, чтобы указать, к чему должен обращаться this:

$("#thing").after($("<div>click me</div>").click(function() {
    barf.apply(document); // now this refers to the document
});

Ответ 5

Получить книгу: JavaScript: хорошие детали.

Кроме того, прочитайте как можно больше Дугласа Крокфорда http://www.crockford.com/javascript/

Ответ 6

Это потому, что это всегда экземпляр, к которому привязана функция. В случае EventHandler это класс, который вызвал событие.

Вы можете помочь себе с анонимной функцией:

function foo() {
  var obj = this;
  $("#thing").after($("<div>click me</div>").click(function(){obj.bar();}));
}

foo.prototype.bar = function() {
  alert(this);
}

Ответ 7

this.bar();  // when called here, "this" is the foo instance

этот комментарий неверен, когда foo используется как нормальная функция, а не как конструктор. здесь:

foo();//this stands for window