jQuery / JavaScript "это" указатель путаница - PullRequest
25 голосов
/ 02 апреля 2009

Поведение «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);
}

Ответы [ 7 ]

35 голосов
/ 02 апреля 2009

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

Вы попали в сферу охвата и закрытия javascript.

Для краткого ответа:

this.bar()

выполняется в рамках foo , (как это относится к foo )

var barf = this.bar;
barf();

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

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

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

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

barf();

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

barf.apply(this);

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

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

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

5 голосов
/ 02 апреля 2009

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

3 голосов
/ 02 апреля 2009
2 голосов
/ 02 апреля 2009

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

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

2 голосов
/ 02 апреля 2009

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

$("#thing").after($("<div>click me</div>").click(function() {
    barf.apply(document); // now this refers to the document
});
1 голос
/ 02 апреля 2009

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

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

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

foo.prototype.bar = function() {
  alert(this);
}
0 голосов
/ 01 февраля 2014
this.bar();  // when called here, "this" is the foo instance

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

foo();//this stands for window
...