【问题标题】:"this" inside a closure function闭包函数中的“this”
【发布时间】:2013-11-27 12:20:02
【问题描述】:

this 在闭包内。 需要注意的是,闭包不能使用 this 关键字访问外部函数的 this 变量,因为 this 变量只能被函数本身访问,不能被内部函数访问。

例如:

var user = {
tournament:"The Masters",
data      :[
{name:"T. Woods", age:37},
{name:"P. Mickelson", age:43}
],

clickHandler:function () {
// the use of this.data here is fine, because "this" refers to the user object, and data is a property on the user object.

this.data.forEach (function (person) {
// But here inside the anonymous function (that we pass to the forEach method), "this" no longer refers to the user object.
// This inner function cannot access the outer function's "this"

console.log ("What is This referring to? " + this); //[object Window]

console.log (person.name + " is playing at " + this.tournament);
// T. Woods is playing at undefined
// P. Mickelson is playing at undefined
})
}

}

user.clickHandler(); // What is This referring to? [object Window]

我的问题是:为什么下面some functionthis指的是jquery的按钮对象而不是窗口对象。毕竟回调函数(某个函数)还在另一个函数中(点击)。

$("button").click (一些函数);

另外,我查看了关于 SO 的另一个类似问题,但我仍然不明智。 "this" keyword inside closure

【问题讨论】:

    标签: javascript


    【解决方案1】:

    我的问题是:为什么下面的某些函数是指 jquery 的按钮对象而不是窗口对象。

    因为 jQuery 通过Function#call function(或者可能是Function#apply,我必须查看jQuery 源代码)显式调用设置this 含义的处理程序。

    这是一个使用call的简单示例:

    function foo() {
        console.log("this.answer = " + this.answer);
    }
    
    var obj = {answer: "42"};
    foo.call(obj); // The first argument is used as `this` during the call
    

    那会输出

    this.answer = 42

    【讨论】:

    • 所以,基本上我们一直使用 call 或 apply 直到我们将“this”设置为我们希望它引用的内容。即 $("button").click (object.somefunction.call(obj)) 对吗?
    • @Tomatoes:不,该代码会立即调用object.somefunction并将其结果传递给$("#button").click()。我要说的是this 指的是click 回调中的DOM 元素(不是jQuery 对象),因为jQuery 故意确保它这样做。在内部,jQuery 通过call(或apply)调用你的处理程序来做到这一点。
    • 我试图在object.somefunction.call(obj)) 中将this 设置为obj,但我正在破坏讨论。我知道 $(this) 指的是 jquery 对象,this 回退到 javascript this。但认为this 在单击内的回调函数中引用了 $("button") jquery 对象,因为通常this 指的是启动包含this 的函数的对象。
    • 所以从你所说的,this 在 click 内的回调函数中应该引用启动对象 $("button") jquery 对象,但 jquery 使它故意引用 DOM 元素(窗口对象)?
    • @Tomatoes:不,将回调传递给以任何方式定义调用回调时this 将是什么的函数没有任何内在意义。这完全由您将回调传递到的 API 定义。 (回复您的电子邮件:是的,SO 会通知人们回复。)
    【解决方案2】:

    你说得对,'this' 关键字指的是当前正在执行的方法已被调用的对象。因此,在您的第一个示例中,clickHandler() 函数将引用用户对象。

    现在就 jQuery 而言,当您在回调函数内部时,“this”指的是“DOM”元素。据我了解,这样做的原因是 jQuery 从其内部“jQuery”代码返回一个对象,该对象使用 call() 和 apply() 维护对上下文中元素的引用,即“DOM”元素。我相信保持它。这样做还可以让您完成诸如("button").click(somefunction).fadeIn() 之类的操作链接。

    如果你创建自己的 jquery 函数,例如 $.fn.somefunction = function() {...},此时 this 指的是一个 jQuery 对象。

    可能有更好的理由来完成此操作,但我很快使用 call() 更改了您的代码以引用您的用户对象。

    var user = {
        tournament:"The Masters",
        data      :[
            {name:"T. Woods", age:37},
            {name:"P. Mickelson", age:43}
        ],
    
        clickHandler: function () {
        // the use of this.data here is fine, because "this" refers to the user object, 
        // and data is a property on the user object.
    
        this.data.forEach (function (person) {
            // But here inside the anonymous function (that we pass to the forEach method),
            //"this" no longer refers to the user object.
            // This inner function cannot access the outer function's "this"
    
            //Use call to make this refer to your user object
            that = Object.call(this, user);
    
             console.log ("What is This referring to? " + that); //[object Object]
    
             console.log (person.name + " is playing at " + that.tournament);
             // T. Woods is playing at undefined
             // P. Mickelson is playing at undefined
            })
         }
    
        }
    
    user.clickHandler(); // What is This referring to? [object Object]
    

    另一件事是在 Javascript 中,forEach 函数采用第二个参数,该参数将用作“this”引用的对象,因此您可以通过另一种方式来完成它。现在 this 指的是用户对象。

    ....
    
    this.data.forEach (function (person) {
        // But here inside the anonymous function (that we pass to the forEach method),
        //"this" no longer refers to the user object.
        // This inner function cannot access the outer function's "this"
    
        //Use call to make this refer to your user object
    
         console.log ("What is This referring to? " + this); //[object Object]
    
         console.log (person.name + " is playing at " + this.tournament);
         // T. Woods is playing at Masters
         // P. Mickelson is playing at Masters
         //pass user as the object the second parameter
        }, user)
     }
    
    }
    

    在 jquery 网站上查看对此的解释,这里有一个链接。

    http://learn.jquery.com/javascript-101/this-keyword/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-13
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 2018-02-19
      相关资源
      最近更新 更多