I have a very simple question of what is better to do (or if at least is correct) when passing a function as argument that uses the this
.
我有一个非常简单的问题,即在将函数作为使用this的参数传递时,最好做什么(或者至少是正确的)。
The better way to explain this is with an example:
更好的解释方法是举个例子:
Let's say I want to fadeOut
an object and then remove it from the DOM. So I will do this:
假设我想fadeOut一个对象然后从DOM中删除它。所以我会这样做:
$("ul li.active").fadeOut(function() {
$(this).remove();
});
Or should I do this? Is this correct? (It works but maybe it is a bad practice)
或者我应该这样做?它是否正确? (它有效,但可能是一个不好的做法)
$("ul li.active").fadeOut($(this).remove);
I didn't find anything relative to this on any question, so I want to know.
在任何问题上我都没有发现任何相关内容,所以我想知道。
1 个解决方案
#1
4
Your second example doesn't work (the element fades out, but it is not removed — the callback doesn't know which element to remove, and so removes none). It fails because the remove
function expects to be called with this
referring to a jQuery instance, and when you set up the callback that way, it gets called with this
referring to a DOM element instead.
你的第二个例子不起作用(元素淡出,但没有删除 - 回调不知道要删除哪个元素,因此不删除任何元素)。它失败了,因为remove函数希望用这个引用jQuery实例来调用,当你以这种方式设置回调时,它会调用它来引用一个DOM元素。
In the specific case of most jQuery callbacks, your first form is the standard way to do it:
在大多数jQuery回调的特定情况下,您的第一个表单是执行此操作的标准方法:
$("ul li.active").fadeOut(function() {
$(this).remove();
});
The reason this is standard is that jQuery sets the value of this
to the specific DOM element related to the event. (With some callbacks it's something other than DOM element, but that's the usual thing.)
这是标准的原因是jQuery将this的值设置为与事件相关的特定DOM元素。 (对于一些回调,它不是DOM元素,但这是通常的事情。)
Or of course, if you need to do that a lot, you might have a named function you can reuse:
或者当然,如果你需要做很多事情,你可能有一个可以重用的命名函数:
function removeCallback() {
$(this).remove();
}
$("ul li.active").fadeOut(removeCallback);
// ...elsewhere...
$("some other selector").fadeOut(removeCallback);
In the general case, not specifically related to jQuery, if you need to set up a method callback on a specific object (so, you want to be in control of what this
is), you can use ES5's Function#bind
to avoid creating unnecessary closures.
在一般情况下,与jQuery没有特别的关系,如果你需要在特定对象上设置一个方法回调(所以,你想控制它是什么),你可以使用ES5的Function#bind来避免创建不必要的关闭。
doSomethingAndCallMeBack(this.method.bind(this));
There, we're using this.method.bind(this)
to create a function that, when called, will call this.method
ensuring that this
within the method is the same thing it means in our code. If we just did this:
在那里,我们使用this.method.bind(this)来创建一个函数,当调用它时,将调用this.method,确保方法中的这与我们的代码中的含义相同。如果我们这样做:
doSomethingAndCallMeBack(this.method); // <== Can be wrong
...we're relying on doSomethingAndCallMeBack
to know what this
value to use (nothing is passed to it above to tell it, it would have to already know).
...我们依靠doSomethingAndCallMeBack知道这个值的用途(上面没有任何内容传递给它,它必须已经知道)。
But since jQuery usually sets this
to a useful value, that's slightly less common in jQuery code.
但是由于jQuery通常会将其设置为有用的值,因此在jQuery代码中稍微不那么常见。
More on this (ugh, no pun) on my blog:
更多关于这个(呃,没有双关语)在我的博客上:
- Mythical methods
- 神话方法
- You must remember
this
- 你必须记住这一点
#1
4
Your second example doesn't work (the element fades out, but it is not removed — the callback doesn't know which element to remove, and so removes none). It fails because the remove
function expects to be called with this
referring to a jQuery instance, and when you set up the callback that way, it gets called with this
referring to a DOM element instead.
你的第二个例子不起作用(元素淡出,但没有删除 - 回调不知道要删除哪个元素,因此不删除任何元素)。它失败了,因为remove函数希望用这个引用jQuery实例来调用,当你以这种方式设置回调时,它会调用它来引用一个DOM元素。
In the specific case of most jQuery callbacks, your first form is the standard way to do it:
在大多数jQuery回调的特定情况下,您的第一个表单是执行此操作的标准方法:
$("ul li.active").fadeOut(function() {
$(this).remove();
});
The reason this is standard is that jQuery sets the value of this
to the specific DOM element related to the event. (With some callbacks it's something other than DOM element, but that's the usual thing.)
这是标准的原因是jQuery将this的值设置为与事件相关的特定DOM元素。 (对于一些回调,它不是DOM元素,但这是通常的事情。)
Or of course, if you need to do that a lot, you might have a named function you can reuse:
或者当然,如果你需要做很多事情,你可能有一个可以重用的命名函数:
function removeCallback() {
$(this).remove();
}
$("ul li.active").fadeOut(removeCallback);
// ...elsewhere...
$("some other selector").fadeOut(removeCallback);
In the general case, not specifically related to jQuery, if you need to set up a method callback on a specific object (so, you want to be in control of what this
is), you can use ES5's Function#bind
to avoid creating unnecessary closures.
在一般情况下,与jQuery没有特别的关系,如果你需要在特定对象上设置一个方法回调(所以,你想控制它是什么),你可以使用ES5的Function#bind来避免创建不必要的关闭。
doSomethingAndCallMeBack(this.method.bind(this));
There, we're using this.method.bind(this)
to create a function that, when called, will call this.method
ensuring that this
within the method is the same thing it means in our code. If we just did this:
在那里,我们使用this.method.bind(this)来创建一个函数,当调用它时,将调用this.method,确保方法中的这与我们的代码中的含义相同。如果我们这样做:
doSomethingAndCallMeBack(this.method); // <== Can be wrong
...we're relying on doSomethingAndCallMeBack
to know what this
value to use (nothing is passed to it above to tell it, it would have to already know).
...我们依靠doSomethingAndCallMeBack知道这个值的用途(上面没有任何内容传递给它,它必须已经知道)。
But since jQuery usually sets this
to a useful value, that's slightly less common in jQuery code.
但是由于jQuery通常会将其设置为有用的值,因此在jQuery代码中稍微不那么常见。
More on this (ugh, no pun) on my blog:
更多关于这个(呃,没有双关语)在我的博客上:
- Mythical methods
- 神话方法
- You must remember
this
- 你必须记住这一点