假设我们有以下示例Javascript代码:
var modeller = "foo";
var provider1 = function (modeller, content, optionalArg) {
alert("this: " + this + ", content: " + content + ", optionalArg: " + optionalArg);
}.bind(null, modeller);
var provider2 = function (content, optionalArg) {
alert("this: " + this + ", content: " + content + ", optionalArg: " + optionalArg);
};
var createConsumer = function () {
// some arbitrary private vars
var content = 1;
var option = 2;
var doConsume = function(provider) {
provider.apply(this, [content, option])
};
return {consume: doConsume};
};
// Now use them
var consumer = createConsumer();
consumer.consume(provider1);
consumer.consume(provider2);
为了演示目的,这简化了很多,但要点是provider1
已经绑定,而provider2
不是 - 消费者不能将自己作为this
参数传递给{ {1}}。
问题:有没有办法检测已绑定函数的情况?有没有办法让provider1
将消费者用作provider1
?假设答案是否定的,那么解决这种情况的最佳方法是什么?
答案 0 :(得分:4)
“有没有办法检测这种函数已被绑定的情况?”
没有
“有没有办法让
provider1
将consumer
用作this
?”
没有
“......解决这种情况的最佳方法是什么?”
因为看起来你想要绑定一个参数而不是this
值,我会在Function.prototype
上创建一个参数binder方法,它返回一个只绑定了参数的函数,而不是{{ 1}}。
this
然后你会像这样使用它:
Function.prototype.argBind = function() {
var _slicer = [].slice,
orig_args = _slicer.call(arguments),
orig_func = this;
return function() {
return orig_func.apply(this, orig_args.concat(_slicer.call(arguments)));
};
};
现在,var modeller = "foo";
var provider1 = function (modeller, content, optionalArg) {
alert("this: " + this + ", content: " + content + ", optionalArg: " + optionalArg);
}.argBind(modeller);
函数将被调用,但是给出了正常的provider1
值,但this
将被绑定为第一个参数。
答案 1 :(得分:0)
有一种方法可以检测某个函数是否已经绑定但是它不是很优雅:
/\[native code]/.test(foo.toString());
绑定函数具有toString()的本机代码。这适用于Chrome(NodeJS)。我不了解其他浏览器。
答案 2 :(得分:0)
以下是一些示例代码,它演示了 apply() 和 call() 的第一个参数不会改变绑定函数中“this”的值:
let bf = f .bind (123);
let n = bf.call (234);
let n2 = bf.apply (234);
ok (n === 123);
ok (n2 === 123);
function f ()
{ return this;
}
(上面的 ok() 是一个函数,如果调用的参数不真实,则会抛出错误)。
你能检测一个函数是否被绑定了吗?
以上 Mihai Voicescu 的回答在我看来是正确的。一种变体是:
将一些唯一的字符串(例如说您的名字作为函数的作者)放入您稍后要测试“绑定”的函数源代码中的注释中。取被测函数的 toString() 。如果这不包括它在原始来源中的唯一字符串,那么您就知道它是一个界限。最好像往常一样测试您想要支持的浏览器。
解决这种情况的最佳方法是什么?
使用普通的可选参数传入您要用作“substitute-this”的对象。例如,称其为“自我”。 'self' 参数可以将其默认值声明为 'this'。然后在函数内部到处使用“self”而不是“this”。默认情况下,它的值将与绑定的“this”相同,但您可以通过为可选参数“self”传入一个不同的显式值来更改它。如果您确实想使用绑定的“this”,则根本不需要传入可选的自参数。