function.apply.bind如何在以下代码中工作?

时间:2016-10-06 22:59:29

标签: javascript promise ecmascript-6 bind apply

所以我得到了一个[200,599]的数组从promise返回,并且spread内部的回调函数被传递给Function.apply.bind,但现在我输了。如何将[200,599]的数组分成x和y? apply.bind究竟是如何工作的?

AND_perceptron = perceptron([
  {Input:[0,0],Output:0},
  {Input:[0,1],Output:0},
  {Input:[1,0],Output:0},
  {Input:[1,1],Output:1}
])

OR_perceptron = perceptron([
  {Input:[0,0],Output:0},
  {Input:[0,1],Output:1},
  {Input:[1,0],Output:1},
  {Input:[1,1],Output:1}
])

XOR_perceptron = perceptron([
  {Input:[0,0],Output:0},
  {Input:[0,1],Output:1},
  {Input:[1,0],Output:1},
  {Input:[1,1],Output:0}
])

test_x1 = 0
test_x2 = 1 

//first layer of perceptrons
and_result   = AND_perceptron.compute(test_x1,test_x2)
or_result    = OR_perceptron.compute(test_x1,test_x2)

//second layer
final_result = XOR_perceptron.compute(and_result,or_result)

4 个答案:

答案 0 :(得分:9)

.apply()是函数对象的一种方法。像这样:



console.log(Math.max.apply(null, [1, 2, 3])); // 3




.apply()接受两个参数,即上下文(目标函数内部将成为this)和一个可迭代的参数(通常是数组,但arguments数组也可以工作)。

.bind()是函数对象的一种方法。像这样:



const x = {
  foo: function() {
    console.log(this.x);
  },
  x: 42
}

var myFoo = x.foo.bind({x: 5});

x.foo(); // 42
myFoo(); // 5




.bind()获取上下文(将成为this),以及可选的其他参数,并返回新函数,上下文绑定,并锁定了其他参数

由于.apply()本身就是一个函数,它可以与.bind()绑定,如下所示:

Function.prototype.apply.bind(fn, null);

意味着this的{​​{1}}为.apply(),而fn的第一个参数为.apply()。意思是它看起来像这样:

null

哪会传播数组中的参数。

答案 1 :(得分:6)

Spread需要一个函数binds apply method,部分应用null参数。简而言之,

spread(fn)

转换为

args => fn.apply(null, args)

与使用ES6扩展语法

相同
args => fn(...args)

函数的名字来自。

如果您想要长答案,请记住bind的作用:

method.bind(context, ...args1)

返回一个类似于

的函数
(...args2) => method.call(context, ...args1, ...args2)

在我们的案例中,methodapplycontextfn,第一个参数为null,因此调用

Function.apply.bind( fn, null )

将创建一个像

一样的函数
(...args2) => (Function.apply).call(fn, null, ...args2)

这相当于上面的fn.apply(…)调用,因为apply是在两次访问中从Function.prototype继承的方法。

答案 2 :(得分:3)

spread函数只是一个实用函数,用于将数组转换为传递给函数的参数。 apply正在进行转换,bind将它绑定到调用函数,以便" this" context连接到同一个函数。

要了解传播如何以更简单的形式运作 - >

spread(function (x,y){console.log(x,y);})([1,2])

你会得到答案,1 2,因为1传递给x,2传递给y。

因此,在您的示例中,您的promise.all将返回一组已解析的promise。 然后将这些参数映射到函数(x,y)的参数。

答案 3 :(得分:1)

它起作用的原因是apply的“解构”性质(如果给定一个值数组,它们将提供给您使用的应用函数)。

现在回到在应用上调用bind时的代码,返回的值是一个函数,该函数返回提供给bind的相同函数,唯一不同的是执行时将使用apply进行调用(在您的情况下,数组为thisArg),但是除非您调用它,否则它将不会执行。 在您的诺言已解决的情况下,then提供的功能将与Promise分辨率提供的参数数组一起执行。

function spread(fn){
   let boundedFn = fn.bind(fn)

   return function(arg){
      return boundedFn.apply(null,arg)
   }
}
   
spread((x, y, c) => console.log(x, y, c))([1,2,3])

// or

Promise.resolve([6, 5]).then(spread((a, b) => console.log(a, b)))

在您的代码中为bind提供null作为第二个参数的原因是为了防止将调用方提供的数组作为第一参数提供给apply。为this保留。