我非常喜欢ES5的Function.prototype.bind
和currying参数(基本上为函数创建默认参数)。
我有点傻逼,但我不能为我的生活找出自己的构造了。这是我的游乐场:
function hello( arg1, arg2 ) {
console.log('hello()');
console.log('"this" is: ', this);
console.log('arguments: ', arguments);
}
var foo = Function.prototype.call.bind( hello,{what: 'dafuq'}, 2 );
foo( 42 );
此日志输出如下:
hello()
"this" is: Object{ what="dafuq" }
arguments: [2,42]
但我不明白{what: 'dafuq'}
对象如何在this
内作为foo
的参考。据我了解,我们正在创建一个绑定调用到Function.prototype.call
。让我们快速检查.bind()
的MDN概要:
fun.bind(thisArg[, arg1[, arg2[, ...]]])
因此,thisArg
.call
是hello
函数,后跟参数列表。基本上会发生什么呢
Function.prototype.call.call( hello, {what: 'dafuq'}, 2);
...呃现在我的大脑有点疼。我想我现在有了一个想法会发生什么,但请有人找到可靠的单词来详细解释它。
{what: 'dafuq'}
如何成为this reference
答案 0 :(得分:8)
你没有打电话给.bind(thisArg, args)
,而是打电话
Function.prototype.bind.call(thisArgUsedByCall, thisArgUsedByBind, argument)
。
显示发生情况的另一种方式:
// thisArgUsedByCall is a function
Function.prototype.call(thisArgUsedByCall, ...) // does the same as:
thisArgUsedByCall.bind(thisArgUsedByBind, argument);
答案 1 :(得分:6)
但我不明白
{what: 'dafuq'}
对象是如何在foo中作为参考的?
这是因为foo
实际上是call
方法,hello
函数绑定为调用上下文,并且该对象绑定为第一个参数。 .call
的第一个参数设置其调用上下文的调用上下文。既然你绑定了它,就意味着对象总是调用上下文。
这样说吧......
您已将.call
的调用上下文绑定到hello
。
这与做......实际上是一样的。
hello.call();
// or...
// Function.prototype.call.call(hello);
您还将.call
的第一个参数绑定到{what: "dafuq"}
,因此这实际上与执行... {/ p>相同
hello.call({what: "dafuq"});
// or...
// Function.prototype.call.call(hello, {what: "dafuq"});
最后,你将.call
的第二个参数限制为2
,所以这实际上和做... {/ p>
hello.call({what: "dafuq"}, 2);
// or...
// Function.prototype.call.call(hello, {what: "dafuq"}, 2);
答案 2 :(得分:2)
简短的回答是bind使用第一个参数并将其用作 this ,但是然后调用消耗其第一个参数(这是bind的第二个参数)。
Bind的工作原理如下:
fun.bind(thisArg, argArgs...)(x, y, ...)
变为
fun(argArgs..., x, y, ....) // this = thisArg
所以
foo( 42 )
是
Function.prototype.call.bind( hello, { what: 'dafuq' }, 2 ) ( 42 )
成为
Function.prototype.call({ what: 'dafuq' }, 2, 42) // this = hello
呼叫的工作原理如下:
fun.call(thisArg, argArgs)
变为
fun(argArgs) // this = thisArg
所以
call({ what: 'dafuq' }, 2, 42) // this = hello
变为
hello(2, 42) // this = { what: 'dafuq' }