25

调用函数时“this”的行为bar让我感到困惑。请参阅下面的代码。当从点击处理程序调用 bar 时,有没有办法将“this”安排为普通的旧 js 对象实例,而不是作为 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);
}
4

7 回答 7

36

欢迎来到 javascript 的世界!:D

您已经进入了 javascript 范围和闭包的领域。

对于简短的回答:

this.bar()

在foo的范围内执行,(因为this指的是foo

var barf = this.bar;
barf();

在全局范围内执行。

this.bar 基本上意味着:

在this (foo)的范围内执行 this.bar 指向的函数。当您将 this.bar 复制到 barf 时,然后运行 ​​barf。Javascript 理解为,运行 barf 指向的函数,由于没有this,它只是在全局范围内运行。

要更正此问题,您可以更改

barf();

像这样:

barf.apply(this);

这告诉 Javascript 在执行它之前将this的范围绑定到 barf。

对于 jquery 事件,您将需要使用匿名函数,或者在原型中扩展绑定函数以支持范围。

欲了解更多信息:

于 2009-04-02T16:55:37.507 回答
5

QuirksModethis对 JavaScript 中的关键字有很好的解释。

于 2009-04-02T16:58:10.450 回答
3

你可能会发现:

在 jQuery 事件中控制“this”的值

或这个:

http://www.learningjquery.com/2007/08/what-is-this

有用。

于 2009-04-02T16:59:40.477 回答
2

您可以使用Function.apply函数来设置this应该引用的内容:

$("#thing").after($("<div>click me</div>").click(function() {
    barf.apply(document); // now this refers to the document
});
于 2009-04-02T16:46:05.313 回答
2

获取这本书:JavaScript:好的部分。

另外,尽可能多地阅读 Douglas Crockford http://www.crockford.com/javascript/

于 2009-04-02T17:10:04.553 回答
1

这是因为this始终是函数附加到的实例。在 EventHandler 的情况下,它是触发事件的类。

您可以使用这样的匿名函数来帮助自己:

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

foo.prototype.bar = function() {
  alert(this);
}
于 2009-04-02T16:41:47.320 回答
0
this.bar();  // when called here, "this" is the foo instance

当 foo 用作普通函数而不是构造函数时,此注释是错误的。这里:

foo();//this stands for window
于 2014-02-01T03:00:18.127 回答