繁体   English   中英

对javascript中的'this'关键字感到困惑

[英]Confused about the 'this' keyword in javascript

我已经很久没有使用Javascript了,今天一直在刷新自己。 总是让我着迷的一件事是this关键字。 我知道在jQuery事件处理程序(例如click事件)中, this是指触发事件的元素。 即使我的函数没有参数, this如何传递给作为回调的函数?

给出以下代码:

$("tr.SummaryTbRow").data("Animating", false);
$("tr.SummaryTbAltRow").data("Animating", false);

$("tr.SummaryTbRow").click(function () {
    if ($(this).data("Animating") == false) {
        if ($(this).next(".Graph").css("display") == "none") {
            $(this).data("Animating", true);

            //Part I am questioning.
            setTimeout(function () {
                $(this).data("Animating", false);
            }(this), 550);

            $(this).next(".Graph").slideRow('down', 500);
        }
        else {
            $(this).data("Animating", true);
            $(this).next(".Graph").slideRow('up', 500);
        }
    }
});

我试图弄清楚如何将带有类SummaryTbRow的元素表行SummaryTbRow给我的setTimeout回调函数。 jQuery是否以类似于我使用匿名回调函数的方式传递了this 我的函数内的this是否指代我传入的this

我知道我可以做:

setTimeout(function (element) {
    $(element).data("Animating", false);
}(this), 550);

但是,我想弄清楚的jQuery是如何能够通过this我的回调函数,即使我的函数接受0参数。

为了回答您的最后一个问题,您可以将您选择的接收者传递给javascript中的函数,用于示例调用

someFunction.call(someObject);

someFunction内部, this将是someObject

就您而言,您似乎想要的是

setTimeout(function (element) {
    $(element).data("Animating", false);
}, 550, this); // this will be passed as element to the callback

或( 更兼容

var _this = this;
setTimeout(function () {
    $(_this).data("Animating", false);
}, 550); 

简短答案:

您可以设置this使用功能的上的功能.call().apply()方法。

长答案:

任何函数上的this变量都类似于arguments变量(这可能是您所不知道的)。 它是在调用函数时设置的,它是函数调用方式的构件。 为了解释,让我从arguments 考虑:

myFunction = function () {
    return arguments.length;
};

现在,让我们看一下对myFunction的几个调用:

myFunction(); //is 0
myFunction(null); //is 1
myFunction(undefined); //is 1
myFunction(0, 0, 0, 0, 0); //is 5

正如你所看到的,价值arguments.length不依赖于如何或在哪里我们写的功能,但我们如何调用该函数。 this变量(也称为“调用对象”)也是如此。 设置调用对象的方法恰好有3种(ES5中大约有4种,但我们将忽略它):

  1. 您可以通过使用点符号调用函数来设置它(例如, something.myFunction()
  2. 您可以通过使用该功能的设置.call().apply()方法(如myFunction.call(someObject)
  3. 如果未使用方法1或方法2进行设置,则默认使用全局对象(例如window

因此,大多数人习惯于方法1。 如果将函数分配为对象的属性,然后使用对象和点符号调用函数,则对象将设置为this 像这样:

var myFn = (function () { return this.x });

var myObj = {
    x: 1,
    y: myFn
};

myObj.myFn(); //is 1

但是,如果myFn不是我们要调用的对象的属性,但是该对象遵循正确的形式使myFn可以对其执行操作,则我们也可以使用方法2(请参阅:鸭子键入):

var myOtherObj = {
    x: 2
}

myFn.call(myOtherObj); //is 2
myFn.apply(myOtherObj); //is 2
myFn.apply({ x : 3}); //is 3

很酷吧? jQuery就是这样做的。 当他们执行回调函数,他们这样做用.apply(event.target)设置this到事件的目标对象)。 由于使用了callbacks框架,因此它们以更复杂的方式进行操作, 但是这个想法就存在了

无论如何,如果我不扔方法3的解释,那我就不会给出很长的答案,这使一些人完全发疯:如果不设置调用对象会发生什么?

因为所有全局变量都是全局对象的隐式属性,所以您可以从方法3中获得一些有趣的效果。 如:

var x = 4;
myFn(); //is 4

但是大多数时候,您不是很幸运地使您的全局对象满足函数对其调用对象的要求,因此通常只会导致错误和很多挫败感。

可能比您期望的要多,但希望您现在对调用对象及其巧妙的方式有了更多的了解。

您可以使用fn.callfn.apply调用函数,这两个函数都带有用于this的上下文参数。

Applycallbind方法用于此目的。 就您而言,您只需编写:

setTimeout(function() {
  $(this).data("Animating", false);
}.bind(this), 550);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM