Javascript Function.prototype.call()

时间:2015-06-26 13:36:54

标签: javascript functional-programming

我读了一些文章,它说下面两行正在做同样的事情。

fn.call(thisValue);
Function.prototype.call.call(fn, thisValue);

对于第1行,我的理解是Javascript中的每个函数对象都有从call继承的方法Function.prototypecall方法的作用是{{1} this的函数定义中的关键字是fn(我在调用方法中传递的第一个参数。thisValue是一个函数,所以我在fn中所做的只是调用fn.call(thisValue)并将函数内的fn关键字设置为this

但对于第2行,我没有得到它。有人可以帮助解释一下第2行正在做什么。

2 个答案:

答案 0 :(得分:6)

让我们从这个设置开始:

function fn() { console.log(this); }
var thisvalue = {fn: fn};

现在您肯定了解thisvalue.fn()是方法调用,并将记录的this值设置为thisvalue对象。

接下来,您似乎知道fn.call(thisvalue)执行完全相同的调用。或者,我们可以将(thisvalue.fn).call(thisvalue)(仅用于结构的括号,可以省略)写为thisvalue.fn === fn

thisvalue.fn(…); // is equivalent to
(thisvalue.fn).call(thisvalue, …); // or:
(fn).call(thisvalue, …);

好的,但fn.call(…)也只是方法调用 - fn函数调用call method函数。
它可以这样访问,因为所有函数对象都从.call继承了这个Function.prototype属性 - 它不是.fn对象上thisvalue之类的自有属性。但是,fn.call === Function.prototype.callthisvalue.fn === fn相同。

现在,我们可以将.call的方法调用重写为.call()的显式调用:

fn.call(thisvalue); // is equivalent to
(fn.call).call(fn, thisvalue); // or:
(Function.protoype.call).call(fn, thisvalue);

我希望你能发现这种模式,现在可以解释为什么以下工作:

Function.prototype.call.call.call(Function.prototype.call, fn, thisvalue);
var call = Function.prototype.call; call.call(call, fn, thisvalue);

打破这个问题留给读者一个练习: - )

答案 1 :(得分:0)

由于我最终在这里试图理解this question,我也会在这里发布我的答案。

让我们从这开始:

get

所以让我们深入挖掘并尝试重新实现function fn() { console.log(this); } fn.a = function(){console.log(this)} // "this" is fn because of the . when calling fn.a() // function fn() { console.log(this); } 函数:

call

因此,当我们这样做时: Function.prototype.fakeCall = function () { // taking the arguments after the first one let arr = Array.prototype.slice.call(arguments, 1); try{ return this.apply(arguments[0], arr); }catch(e){} } function a(ar){ console.log(ar + this.name) }; let obj = {name : "thierry"}; // a.fakeCall( obj, 'hi ') Function.fakeCall.fakeCall(a, obj, 'hi ');

首先,我们有:

  
      
  1. Function.prototype.fakeCall.fakeCall(a, obj, 'hi ')
  2.   
  3. arr = [ obj, 'hi ']
  4.   

所以我们最终得到this = Function.fakeCall

然后在第二轮比赛中我们

  
      
  1. Function.fakeCall.apply(a, [ obj, 'hi ']);
  2.   
  3. arr = ['hi']
  4.   

因此我们最终得到的this = aa.apply(obj, ['hi'])

相同

source