如何将此上下文传递给函数?


213

我以为这是我可以轻松搜索的东西,但是也许我没有问正确的问题...

如何在给定的javascript函数中设置“ this”所指的内容?

例如,与大多数jQuery函数一样,例如:

$(selector).each(function() {
   //$(this) gives me access to whatever selector we're on
});

如何编写/调用自己的独立函数,并在调用时具有适当的“ this”引用?我使用jQuery,因此,如果有jQuery特定的方式可以做到,那将是理想的选择。



我知道这是一个老问题,但是对于其他在此登陆的人,请参见jQuery$.proxy
RyBolt

Answers:


302

Javascript .call().apply()方法允许您设置函数的上下文

var myfunc = function(){
    alert(this.name);
};

var obj_a = {
    name:  "FOO"
};

var obj_b = {
    name:  "BAR!!"
};

现在您可以致电:

myfunc.call(obj_a);

哪个会警惕FOO。相反,通过obj_b将使人警觉BAR!!.call()和之间的区别.apply()是,.call()如果要将参数传递给函数并.apply()需要一个数组,则需要用逗号分隔的列表。

myfunc.call(obj_a, 1, 2, 3);
myfunc.apply(obj_a, [1, 2, 3]);

因此,您可以hook使用该apply()方法轻松编写函数。例如,我们要向jQuerys .css()方法添加功能。我们可以存储原始函数引用,使用自定义代码覆盖函数并调用存储的函数。

var _css = $.fn.css;
$.fn.css = function(){
   alert('hooked!');
   _css.apply(this, arguments);
};

由于魔术arguments对象是类似于对象的数组,因此我们可以将其传递给apply()。这样,我们保证所有参数都传递给原始函数。


4
只是一个有趣的提示:obj_a例如,如果您需要参考来反复调用该函数,则可以使用创建该函数的副本,var boud_myfunc = myfunc.bind(obj_a)bound_myfunc()根据需要简单地进行调用。
wbadart '16

44

用途function.call

var f = function () { console.log(this); }
f.call(that, arg1, arg2, etc);

函数中that想要的对象在哪里this


1
function是保留关键字;由于function.call(...)无效的JavaScript,请考虑更新您的响应以包含命名函数。
Daniel Allen

1
@DanielAllen:如果我没有提供任何示例函数名称的定义,该代码仍将引发JS错误。但是,我更新了示例函数名称。
palswim

16

jQuery使用一种.call(...)方法将当前节点分配给this您作为参数传递的函数内部。

编辑:

如有疑问,不要害怕看一下jQuery的代码,它全部以清晰且有据可查的Javascript编写。

即:这个问题的答案在574行附近,
callback.call( object[ name ], name, object[ name ] ) === false


12

您可以使用bind函数来设置this函数内的上下文。

function myFunc() {
  console.log(this.str)
}
const myContext = {str: "my context"}
const boundFunc = myFunc.bind(myContext);
boundFunc(); // "my context"

12

另一个基本示例:

不起作用:

var img = new Image;
img.onload = function() {
   this.myGlobalFunction(img);
};
img.src = reader.result;

加工:

var img = new Image;
img.onload = function() {
   this.myGlobalFunction(img);
}.bind(this);
img.src = reader.result;

所以基本上:只需将.bind(this)添加到您的函数中


这应该是公认的答案。语法更容易,思想更容易...干得好Joery
nenea
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.