简体   繁体   English

Function.prototype.bind.apply()无法按预期工作

[英]Function.prototype.bind.apply() doesn't work as expected

I've a function myfunc and want to bind it to a specific this argument and other arguments to bind as a single array, not parameters list (cause I get the parameters list as an argument of function, where this code is executed). 我有一个函数myfunc并希望bindbind到特定的this参数和其他参数bind为单个数组,而不是参数列表(因为我将参数列表作为函数的参数,执行此代码)。 For that purpose I use apply on bind as follows: 为此,我使用apply on bind如下:

var myfunc = function(arg1, arg2){
    alert("this = " + this + ", arg1 = " + arg1 + ", arg2 = " + arg2);
}
var bindedMyfunc = myfunc.bind.apply("mythis", ["param1", "param2"]);
bindedMufunc();

This results in Uncaught TypeError: Bind must be called on a function . 这导致Uncaught TypeError: Bind must be called on a function

What am I doing wrong? 我究竟做错了什么? Could you explain in detail, what's going onwhen I run this code, cause reality seems to contradict my opinion on that? 你能否详细解释一下,当我运行这段代码时会发生什么,导致现实似乎与我的看法相矛盾?

Summary of answers: Seems that bind itself has its own this argument, which is the function, it is called on. 答案摘要:似乎bind自身有自己的this参数,它是函数,它被调用。 Eg when you say myfunc.bind(args) , bind 's this is myfunc . 例如,当你说myfunc.bind(args)bindthismyfunc

By calling apply on bind I've mistakingly assigned bind 's this to "mythis", which is not a function and bind can't be called on it. 通过调用apply on bind我错误地将bind的命名分配给了“mythis”,这不是一个函数,并且不能在它上面调用bind

So, the solution is to use 所以,解决方案是使用

myfunc.bind.apply(myfunc, ["mythis"].concat(["param1", "param2"]))

Also, if you want to call the binded myfunc right off, you could say: 此外,如果你想立即调用绑定的myfunc,你可以说:

myfunc.apply.bind(myfunc)("mythis", ["param1", "param2"])

but this doesn't suffice my case, cause I need to pass the binded function as an argument to addEventListener . 但这不足以解决我的问题,因为我需要将绑定函数作为参数传递给addEventListener

Thanks for your help, guys! 谢谢你的帮助,伙计们!

You should use the function as the first parameter to the apply method. 您应该使用该函数作为apply方法的第一个参数。 The use of myfunc.bind doesn't associate the function with the call, it has the effect of Function.prototype.bind , and you can just as well use that. myfunc.bind的使用不会将函数与调用相关联,它具有Function.prototype.bind的效果,您也可以使用它。

The first parameter for the bind method ( thisArg ) should be the first item in the array. bind方法的第一个参数( thisArg )应该是数组中的第一个项目。

var bindedMyfunc = Function.prototype.bind.apply(myfunc, ["mythis", "param1", "param2"]);

Seems that bind itself has its own this argument, which is the function, it is called on. 似乎绑定本身有自己的这个参数,它是函数,它被调用。 Eg when you say myfunc.bind(args) , bind 's this is myfunc . 例如,当你说myfunc.bind(args)bindthismyfunc

Exactly. 究竟。 If you want to apply bind , then you have to apply it to the function (the first parameter), and pass the bind arguments (including the intended this value) as an array (the second paramter): 如果要应用bind ,则必须将其应用于函数(第一个参数),并将bind参数(包括预期的this值)作为数组(第二个参数)传递:

(Function.prototype.bind).apply(myfunc, ["mythis", "param1", "param2"])
// which is equivalent to
myfunc.bind("mythis", "param1", "param2")
(…args) => myfunc.call("mythis", "param1", "param2", …args) // ES6 syntax

However, there is another way to solve your problem: bind apply to the function, and partially apply the proposed apply arguments: 但是,还有另一种方法可以解决您的问题:绑定apply函数,并部分应用建议的apply参数:

(Function.prototype.apply).bind(myfunc, "mythis", ["param1", "param2"])
// which is equivalent to
(…args) => myfunc.apply("mythis", ["param1", "param2"], …args) // ES6 syntax

Maybe you want to bind apply rather than apply ing bind ? 也许你想bind apply而不是apply bind

var bindedMyfunc = Function.prototype.apply.bind(myfunc);
bindedMyfunc('obj', [1, 2]); // this = obj, arg1 = 1, arg2 = 2

I often use this pattern to make hasOwnProperty checks shorter without being shadowable; 我经常使用这种模式使hasOwnProperty检查更短而不会被遮蔽;

var has = Function.prototype.call.bind(Object.hasOwnProperty);
has({foo:1}, 'foo'); // true
has({foo:1}, 'bar'); // false

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

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