[英]Javascript Function.prototype.call()
I read some article and it said the following 2 line are doing the same thing. 我读了一些文章,它说下面的两行正在做同样的事情。
fn.call(thisValue);
Function.prototype.call.call(fn, thisValue);
For line 1, my understanding is that every function object in Javascript do have a the method call
inherited from the Function.prototype
and what call
method does is to have the this
keyword inside the function definition of fn
to be thisValue
(the first parameter I passed in the call method. fn
is a function so what I am doing in fn.call(thisValue)
is just invoking fn
and set the this
keyword inside the function to be thisValue
. 对于第1行,我的理解是Javascript中的每个函数对象都具有从
Function.prototype
继承的方法call
,而call
方法所做的是将fn
函数定义内的this
关键字设为thisValue
(第一个参数I fn
是一个函数,所以我在fn.call(thisValue)
中fn.call(thisValue)
只是调用fn
并将函数内的this
关键字设置为thisValue
。
But For line 2, I don't get it. 但是对于第二行,我不明白。 Can someone help to explain it what the hack the line 2 is doing.
有人可以帮忙解释一下2号线在做什么。
Let's start with this setup: 让我们从此设置开始:
function fn() { console.log(this); }
var thisvalue = {fn: fn};
Now you surely understand that thisvalue.fn()
is a method call, and sets the logged this
value to the thisvalue
object. 现在,您肯定知道
thisvalue.fn()
是一个方法调用,并将记录的this
值设置为thisvalue
对象。
Next, you seem to know that fn.call(thisvalue)
does exactly the same call. 接下来,您似乎知道
fn.call(thisvalue)
完全相同的调用。 Alternatively, we could write (thisvalue.fn).call(thisvalue)
(parentheses just for structure, could be omitted) as thisvalue.fn === fn
: 或者,我们可以写成
(thisvalue.fn).call(thisvalue)
(仅用于结构的括号,可以省略)为thisvalue.fn === fn
:
thisvalue.fn(…); // is equivalent to
(thisvalue.fn).call(thisvalue, …); // or:
(fn).call(thisvalue, …);
OK, but fn.call(…)
is just a method call as well - the call
method of functions is called on the fn
function. 可以,但是
fn.call(…)
也是方法调用-在fn
函数上call
函数的call
方法 。
It can be accessed as such because all function objects inherit this .call
property from Function.prototype
- it's not an own property like .fn
on the thisvalue
object. 它可以作为这样的,因为所有的函数对象继承此访问
.call
物业Function.prototype
-它不是自己的财产一样.fn
上thisvalue
对象。 However, fn.call === Function.prototype.call
is the same as thisvalue.fn === fn
. 但是,
fn.call === Function.prototype.call
与thisvalue.fn === fn
相同。
Now, we can rewrite that method call of .call
as an explicit invocation with .call()
: 现在,我们可以将
.call
方法调用重写为.call()
的显式调用:
fn.call(thisvalue); // is equivalent to
(fn.call).call(fn, thisvalue); // or:
(Function.protoype.call).call(fn, thisvalue);
I hope you spot the pattern and can now explain why the following work as well: 我希望您能发现这种模式,并且现在可以解释以下原因为何:
Function.prototype.call.call.call(Function.prototype.call, fn, thisvalue);
var call = Function.prototype.call; call.call(call, fn, thisvalue);
Breaking this down is left as an exercise to the reader :-) 分解下来留给读者练习:-)
Since I ended up here trying to understand this question , I'm gonna post my answer here as well. 由于我最终在这里试图理解这个问题 ,因此我也将在这里发布答案。
Let's start with this: 让我们从这个开始:
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); }
So let's dig deeper and try to reimplement the call
function: 因此,让我们更深入地尝试重新实现
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 ');
Thus when we do this: Function.prototype.fakeCall.fakeCall(a, obj, 'hi ')
因此,当我们这样做时:
Function.prototype.fakeCall.fakeCall(a, obj, 'hi ')
what happens is, on the first run we have: 发生的是,在第一次运行中,我们有:
arr = [ obj, 'hi ']
this = Function.fakeCall
so we end up with Function.fakeCall.apply(a, [ obj, 'hi ']);
所以我们最后得到
Function.fakeCall.apply(a, [ obj, 'hi ']);
Then on the second run we have 然后在第二轮
arr = ['hi']
this = a
so we end up with a.apply(obj, ['hi'])
which is the same as a.call(obj, 'hi');
所以我们最终得到
a.apply(obj, ['hi'])
与a.call(obj, 'hi');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.