【问题标题】:jQuery/JavaScript "this" pointer confusionjQuery/JavaScript“this”指针混淆
【发布时间】:2010-10-17 04:02:52
【问题描述】:

当函数bar 被调用时“this”的行为让我很困惑。请参阅下面的代码。当从点击处理程序调用 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);
}

【问题讨论】:

  • 请解释"this" is the foo instance。以下 jsfiddle(jsfiddle.net/yY6fp/1) 演示了 this.bar() 中的 this 计算结果为 window(global) 对象。

标签: javascript jquery this


【解决方案1】:

欢迎来到 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 事件,您将需要使用匿名函数,或者在原型中扩展绑定函数以支持范围。

更多信息:

【讨论】:

  • 我自己对术语不是 100% 确定,但我认为这个答案(以及链接到的资源)将“范围”与“执行上下文”混淆了。 this 指向的对象是执行上下文,完全独立于作用域(闭包与之相关)。范围在函数创建时确定,并确定函数可以看到哪些变量;每当调用函数时都会确定执行上下文,并确定this 所指的内容。在这里到处都用“执行上下文”替换“范围”,只有这样它才是正确的——我想!
【解决方案2】:
this.bar();  // when called here, "this" is the foo instance

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

foo();//this stands for window

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 除了代码中缺少右括号这一事实之外 - 函数 apply 会立即执行函数 barf 而不是返回函数指针.
    【解决方案4】:

    获取书籍:JavaScript:优秀部分。

    此外,请尽可能多地阅读 Douglas Crockford 的著作 http://www.crockford.com/javascript/

    【讨论】:

      【解决方案5】:

      【讨论】:

        【解决方案6】:

        QuirksMode 上对 JavaScript 中的 this 关键字有很好的解释。

        【讨论】:

          【解决方案7】:

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

          您可以通过这样的匿名函数帮助自己:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-09-25
            • 2011-09-04
            • 2016-11-08
            • 2012-10-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多