在Javascript中绑定更多已绑定函数的参数

时间:2014-01-04 18:44:50

标签: javascript call bind

我尝试对javascript的bind()如何工作进行排序。

如果我这样做,我会看到

var f = function (a) { ... }
var g = f.bind(obj);
g(1)

然后使用objthis1称为a来调用f。

我认为g是围绕f。

的包装函数

但是当我做的时候

var f = function (a) { ... }
var g = f.bind(obj);
g.call(1)

然后调用f 1thisa未定义。

所以看起来g不仅仅是一个简单的包装器,而且call以某种方式区分了普通函数和绑定函数。

还有一件事是我不能多次部分应用一个功能。

var f = function (a) { ... }
var g = f.bind(obj);
var h = g.bind(1);
h();

然后调用f objthisa未定义。

这种行为的原因是什么?

修改

这个问题中的结构实际上是错误的,看看它们应该是什么样子的接受答案(通常我没有注意到callbind总是需要上下文参数作为第一个论点)。

2 个答案:

答案 0 :(得分:40)

将对象绑定到具有bind的函数后,您无法覆盖它。正如您在MDN documentation中所看到的那样,它清楚地写在规范中:

“bind()函数创建一个新函数(一个绑定函数),它具有相同的函数体(ECMAScript 5术语中的内部调用属性)作为它被调用的函数(绑定函数的目标函数)将此值绑定到bind()的第一个参数,无法覆盖。

这意味着,如果你这样做:

g.call(1);

在符合规范的浏览器上,您将获得obj this而不是1

你当然可以绑定多个参数,所以:

var sum = function(a, b, c) { return a + b + c };
var sumAB = sum.bind(null, 1, 5);
var sumC = sumAB.bind(null, 2);

console.log(sumC());

但是上下文对象将始终是第一个bind指定的对象,因为它不能被覆盖。

为了避免混淆,call的第一个参数是上下文对象(this),那么你将得到其余的参数。

这意味着:

var obj = { foo: function(bar) { console.log(bar) } };

obj.foo('hello');

// equivalent to:
var foo = obj.foo;

foo.call(obj, 'hello');

希望它有所帮助。

答案 1 :(得分:3)

你从未传递任何参数 - 你只设置了上下文。 call的第一个参数作为上下文(this)被接收,并且参数2以后作为被调用函数的参数1和之后被接收。同时,bind使用新的上下文创建一个新函数 - 在调用时传递参数。

以下是从第一个代码块传递1作为函数f的参数a的方法:

f( 1 );
g( 1 );
g.call( this, 1 );
g.apply( this, [ 1 ] );