首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >`bind.bind`是什么意思?一种使用JavaScript绑定的奇怪方法

`bind.bind`是什么意思?一种使用JavaScript绑定的奇怪方法
EN

Stack Overflow用户
提问于 2017-04-17 06:34:05
回答 4查看 2.8K关注 0票数 44

我正在阅读一本关于编写JavaScript框架的书,并找到了这段代码片段。但我不明白它是如何工作的,尤其是bind.bind的用法?有人有线索吗?

代码语言:javascript
复制
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]
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-04-17 09:09:11

这让我回想起求解和扩展方程的日子。

1。首先,让我们扩展第一个应用函数:

代码语言:javascript
复制
var bind = Function.prototype.bind;
var apply = bind.bind(bind.apply);
var fn = apply([].concat);

转换为:

代码语言:javascript
复制
var apply = Function.prototype.bind.bind(Function.prototype.bind.apply);
var fn = apply([].concat)

2 .其次,我们扩展fn函数:

代码语言:javascript
复制
var fn = Function.prototype.bind.bind(Function.prototype.bind.apply)([].concat);

3 .现在,我们发明了一个js代数规则,并将调用替换为调用.

实际上,我们实施了一个替代方案,其基础是:

代码语言:javascript
复制
someFunction.bind(arg1)(arg2) <==> someFunction.call(arg1, arg2)

因此,我们可以替换它并得到:

代码语言:javascript
复制
var fn = Function.prototype.bind.call(Function.prototype.bind.apply, [].concat);

4 .对于我们的第二个js代数规则,我们设计了:

someFn.bind.call(target, ...) <==> target.bind(...)

someFn在这里并不重要,因为我们不对它调用bind()。我们在bind上调用bind--替换曾经是someFnthis,并为此将其替换为target

因此,我们将bind.call(target)替换为target.bind选项。

代码语言:javascript
复制
var fn = Function.prototype.bind.apply.bind([].concat) 

5 .如果最后一次置换也在执行调用(),我们可以执行一个替换,如:

代码语言:javascript
复制
fn([1, 2], [3, 4]) <==> [].concat.apply([1, 2], [3, 4])

但是,我们只有没有调用的绑定,我们可以替换该绑定,并且等效于:

代码语言:javascript
复制
var fn = function (arg1, arg2) { 
    return [].concat.apply(arg1, arg2); 
}
// instead arg1 and arg2 we could use more accurate arguments logic also.

最终结果

代码语言:javascript
复制
var fn = Function.prototype.bind.apply.bind([].concat) 

// or

var fn = function (arg1, arg2) { 
    return [].concat.apply(arg1, arg2); 
}

fn函数接受concat函数,并允许我们使用函数样式,而无需从对象调用它。concat没有绑定到调用方的this,而是将其作为thisarg1上应用,arg2作为连接到arg1的其他参数。

代码语言:javascript
复制
fn([1, 2], [3, [5, 6], 4])
// [1, 2, 3, 5, 6, 4]
票数 36
EN

Stack Overflow用户

发布于 2017-04-17 09:53:49

因为Function.prototype.bind本身就是一个函数,所以它作为一个方法继承自己。

通常,bind作为特定函数的实例方法调用,但我们可以将其重新绑定到Function.prototype.apply并返回一个高阶函数。

一种不那么简洁的写作方式是:

代码语言:javascript
复制
function apply (fn) {
  return function (a, b) {
    return fn.apply(a, b)
  }
}
票数 12
EN

Stack Overflow用户

发布于 2017-04-17 16:59:59

我们必须考虑一下bind在幕后实际做了什么。粗略地说,它的工作方式如下:

代码语言:javascript
复制
function bind(fn, ...bound) {
    return (...other) => this.call(fn, ...bound, ...other);
}

(请记住,词法this引用了调用bind的函数。)所以带着

代码语言:javascript
复制
apply = bind.bind(bind.apply);

并且自己手动扩展bind,我们得到:

代码语言:javascript
复制
apply = (...other) => bind.call(bind.apply, ...other);

我们只对传递一个参数感兴趣,这是一个函数。希望这也意味着它的apply属性与bind的相同。

代码语言:javascript
复制
apply = (fn) => bind.call(fn.apply, fn);

bind本身(希望)也是fn.apply的原型,因此我们可以进一步简化为:

代码语言:javascript
复制
apply = (fn) => fn.apply.bind(fn);

我们现在可以再次扩展bind

代码语言:javascript
复制
apply = (fn) => (...other) => fn.apply.call(fn, ...other);

这一次,我们需要两个参数,对call的调用也可以简化:

代码语言:javascript
复制
apply = (fn) => (obj, args) => fn.apply(obj, args);

我们现在可以在[].concat上调用[].concat

代码语言:javascript
复制
fn = (obj, args) => [].concat.apply(obj, args);

obj需要是一个数组才能工作,因此这简化为:

代码语言:javascript
复制
fn = (obj, args) => obj.concat(...args);

在提供的示例中,我们以

代码语言:javascript
复制
[1, 2, 3].concat(4, [5, 6], 7)

返回预期的结果。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43446378

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档