2010-09-02 54 views
162

我认为这将是我可以很容易地谷歌,但也许我不是问正确的问题...如何将此上下文传递给函数?

我如何设置任何“this”在给定的JavaScript函数中引用?

例如,与大多数的jQuery的功能,如:

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

如何编写/调用有一个适当的“this”引用我自己的独立功能调用时?我使用jQuery,所以如果有一个特定于jQuery的方法,那会很理想。

+0

可能重复:http://stackoverflow.com/questions/520019/controlling-the-value-of-this-in-a-jquery-event/520417#520417 – user123444555621 2010-09-02 18:39:14

+0

我知道这是个老问题,但对于在此处着陆的其他人来说,请参阅jQuery'$ .proxy' – RyBolt 2016-07-15 15:34:33

回答

240

的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]); 

因此,可以很容易地通过使用apply()方法写一个函数hook。例如,我们想为jQuerys .css()方法添加一个功能。我们可以存储原始函数引用,用自定义代码覆盖函数并调用存储的函数。

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

由于魔arguments对象是状物体的阵列,我们只要把它传递给apply()。我们保证这种方式,所有参数都传递给原始函数。

+2

只是一个有趣的小技巧:例如,如果您需要重复调​​用该函数来引用'obj_a',则可以使用'var boud_myfunc = myfunc创建它的副本.bind(obj_a)',并根据需要简单地调用'bound_myfunc()'。 – Will 2016-11-15 07:20:42

37

Use

_function.call(that, arg1, arg2, etc); 

哪里that是要this的功能为对象。

+0

'function'是一个保留关键字;考虑更新你的响应以包含一个命名函数,因为'function.call(...)'不是有效的JavaScript。 – 2017-09-14 14:44:38

+0

@DanielAllen:如果没有我提供的任何示例函数名称的定义,代码仍会抛出JS错误。但是,我更新了示例函数名称。 – palswim 2017-09-15 01:00:45

14

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

编辑:

不要害怕看jQuery的代码中,当你有一个疑问,这一切都在清晰,有据可查的JavaScript。

即:对这个问题的答案是大约574线,
callback.call(object[ name ], name, object[ name ]) === false

1

可以使用bind功能设置功能中的this上下文。

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