对javascript中的'this'关键字感到困惑 [英] Confused about the 'this' keyword in javascript

查看:64
本文介绍了对javascript中的'this'关键字感到困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很长一段时间没有使用过Javascript,而且今天一直在刷新自己。总是有一件事是这个关键字。我知道在jQuery事件处理程序中,例如click事件,这个指的是触发事件的元素。怎么这个传递给我作为回调给它的函数,即使我的函数没有参数?

I haven't used Javascript in a long time and have been refreshing myself on it today. One thing that always got me was the this keyword. I know in jQuery event handlers, such as the click event, this refers to the element that fired the event. How is this passed to the function that I give it as a callback even though my function has no arguments?

给出以下代码:

$("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 到我的setTimeout回调函数。 jQuery是否通过我的匿名回调函数以类似的方式传递这个?该函数中的 this 是否指向我传入的

I am trying to figure out how to pass the element table row with class SummaryTbRow to my setTimeout call back function. Does jQuery pass this in a similar fasion to what I am doing with my anonymous call back function? Does my this inside the function refer to the this I pass in?

我知道我可以做:

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

但我想知道jQuery如何能够传递这个到我的回调函数,即使我的函数有0个参数。

But I want to figure out how jQuery is able to pass this to my call back function even though my function takes 0 arguments.

推荐答案

简答:

您可以设置这个在一个函数上使用函数的 .call() .apply()方法。

You can set this on a function by using the function's .call() and .apply() methods.

长答案:

任何函数的变量类似于 arguments 变量(这可能是你不知道的事情)。它在调用函数时设置,并且是调用函数的工件。为了解释,让我先来演示参数。考虑:

The this variable on any function is similar to the arguments variable (which is probably something you didn't know about). It's set when the function is called and is an artifact of how the function is called. To explain, let me start with a demonstration of arguments. Consider:

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的值不取决于我们编写函数的方式和位置,而是取决于我们调用函数的方式。 这个变量(也称为调用对象)也是如此。设置调用对象的确有3种方法(ES5中有第4种,但我们会忽略它):

As you can see, the value of arguments.length is not dependent on how or where we wrote the function, but on how we called the function. The same is true of the this variable (otherwise known as the "calling object"). There are exactly 3 methods for setting the calling object (there's a sort-of 4th in ES5, but we'll ignore that):


  1. 你可以通过使用点符号调用函数来设置它(例如 something.myFunction()

  2. 你可以使用它来设置它函数的 .call() .apply()方法(例如 myFunction.call( someObject)

  3. 如果没有使用方法#1或#2设置它,它将默认为全局对象(例如 window

  1. You can set it by calling the function using dot-notation (e.g. something.myFunction())
  2. You can set it by using the function's .call() or .apply() methods (e.g. myFunction.call(someObject))
  3. If it's not set using method #1 or #2, it will default to the global object (e.g. window)

所以大多数人都习惯了方法#1。如果将函数指定为对象的属性,则使用object和dot-notation调用该函数,然后将对象设置为 this 。像这样:

So most people are used to method #1. If you assign your function as a property of an object, then call the function using the object and dot-notation, then the object gets set as this. Like so:

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

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

myObj.myFn(); //is 1

但是如果 myFn我们也可以使用方法2 不是我们想要调用它的对象的属性,但该对象遵循 myFn 的正确形式,以便能够对其进行操作(请参阅:duck typing):

But we can also use method 2 if myFn isn't a property of the object we want to call it on but the object follows the correct form for myFn to be able to act on it (see: duck typing):

var myOtherObj = {
    x: 2
}

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

非常酷,是吗?这就是jQuery如何做到的。当他们执行你的回调时,他们使用 .apply(event.target)(将设置为事件的目标)宾语)。他们以更复杂的方式执行它,因为他们的回调框架,但想法就在那里

Pretty cool, eh? This is how jQuery does it. When they execute your callback, they do so using .apply(event.target) (setting this to the event's target object). They do it in a more complex manner because of their callbacks framework, but the idea is there.

无论如何,如果我不提供长篇答案没有抛出方法#3的解释,它驱使一些人完全疯了:如果你没有设置调用对象会发生什么?

Anyway, I wouldn't be offering a long answer if I didn't toss in an explanation of method #3, which drives some people totally insane: What happens if you don't set the calling object?

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

Because all global variables are implicit properties of the global object, you get some interesting effects from method #3. Such as:

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

但是大部分时间你都没有幸运地让你的全局对象相遇该函数对其调用对象的要求,通常只会导致错误和很多挫折。

But most of the time you're not lucky enough to have your global object meet the requirements the function has for its calling object, so usually it just results in an error and a lot of frustration.

可能比你想要的更多,但希望你现在对调用对象及其狡猾的方式更加了解。

Probably more than you were looking for, but hopefully you're now much more informed on the calling object and its wily ways.

这篇关于对javascript中的'this'关键字感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆