我正在阅读一本关于编写JavaScript框架的书,发现了这个代码片段。但是我不明白它是如何工作的,尤其是bind.bind
的用法?有人知道吗?
var bind = Function.prototype.bind;
var apply = bind.bind(bind.apply);
var fn = apply([].concat);
var a = [1, 2, 3], b = [4, [5, 6], 7];
fn(a, b);
//output [1, 2, 3, 4, 5, 6, 7]
5条答案
按热度按时间gpfsuwkq1#
这让我想起了解方程和展开方程的日子。
1 .首先,让我们展开第一个apply函数:
转变为:
2 .其次,我们扩展了fn函数:
3 .我们现在发明了一个js代数规则,并用call调用替换
bind.bind...()
调用。实际上,我们基于以下概念实现替换:
因此,我们可以将其替换为:
4 .对于我们的第二个js代数规则,我们设计如下:
someFn.bind.call(target, ...) <==> target.bind(...)
.someFn
在这里并不重要,因为我们没有在它上面调用bind(),我们在bind
上调用call
-替换原来的someFn
,因此它被替换为target
。因此,我们将
bind.call(target)
替换为target.bind替代项5 .如果最后一个置换也执行invocation(),我们可以执行如下替换:
但是我们只有绑定,没有可以替换的调用,等价于:
最终结果
fn
函数继承了concat
函数,让我们以函数的方式使用它,而不是从对象调用它。fn
不是将concat
绑定到调用者的this
,而是将它作为this
和arg2
应用到arg1
上,作为连接到arg1
的其他参数。ffscu2ro2#
因为
Function.prototype.bind
本身是一个函数,所以它将自身继承为一个方法。通常,bind是作为一个特定函数的示例方法调用的,但是我们可以将它重新绑定到
Function.prototype.apply
并返回一个更高阶的函数。一种不那么简洁的写法是:
cgyqldqp3#
我们必须稍微考虑一下
bind
在幕后的实际作用。粗略地说,它的工作原理是这样的:(请记住,词法
this
指的是调用bind
的函数。)手动展开
bind
,我们得到:我们只对传递一个参数感兴趣,这个参数是一个函数,希望这也意味着它的
apply
属性和bind
相同:但是
bind
(希望)本身也在fn.apply
的原型上,所以我们可以进一步简化为:现在我们可以再次扩展
bind
了:这一次,我们需要两个参数,对
call
的调用也可以简化:现在我们可以在
[].concat
上调用apply
了:obj
需要是一个数组才能正常工作,因此简化为:在所提供的示例中,我们得到了
其返回期望的结果。
ia2d9nvy4#
bind()
方法为传递到bind()
的值创建函数的新示例。在这里,我们通过分解成单独的可执行代码单元来调用
Function.prototype.bind.apply(Function.prototype, [null].concat(arguments));
。目的是调用
apply
;将原始函数作为第一个参数传递,然后作为参数数组传递。这些代码对于每个涉及的进程都有不同的变量,以实现与动态参数的绑定。
最后两行用于通过传递两个参数来执行
fn
函数var a=[1,2,3],b=[4,[5,6],7]; fn(a,b);
ryoqjall5#
示例说明
下面的技术可以用来“uncurry
this
",意思是将一个方法转换成一个函数,其中this
作为第一个参数提供,而不是基于方法调用的对象隐式地提供this
。如果想更深入地了解,我可以推荐:http://web.archive.org/web/20160805225710/http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming