Javascript Function.call、Function.prototype.call、Function.prototype.call.call和Function.prototype.call.call.call之间的差异

Javascript Function.call、Function.prototype.call、Function.prototype.call.call和Function.prototype.call.call.call之间的差异,javascript,functional-programming,prototype,call,Javascript,Functional Programming,Prototype,Call,我已经检查了许多关于stackoverflow的类似问题,例如,但是我是一个新手,我不能在任何地方发表评论。我希望我能找到一个关于JavaScript解释器如何执行这些函数的全面而透彻的解释,并在这里提出一个新问题 以下是一些例子: function my(p) { console.log(p) } Function.prototype.call.call(my, this, "Hello"); // output 'Hello' var $ = Function.prot

我已经检查了许多关于stackoverflow的类似问题,例如,但是我是一个新手,我不能在任何地方发表评论。我希望我能找到一个关于JavaScript解释器如何执行这些函数的全面而透彻的解释,并在这里提出一个新问题

以下是一些例子:

function my(p) { console.log(p) }
Function.prototype.call.call(my, this, "Hello"); // output 'Hello'
var $ = Function.prototype.call
$(my, this, 'Hello5') // Exception: TypeError: Function.prototype.call called on incompatible Proxy
上面的示例是Function.prototype.call的标准用法,更容易理解。我的理解是:“my”作为函数对象执行其继承的方法“function.prototype.call”即.my.(function.prototype.call)=>my.call(这是“Hello”)

与上面的例子相比,我在这里感到困惑。我不知道JavaScript解释器在这里是如何工作的my'将Function.call和Function.prototype.call视为相同的方法

Function.prototype.call(my, this, 'Hello2') // output nothing
Function.call(my, 'Hello2') // output nothing
我无法解释为什么这句话不出错?事实上,我不知道Function.prototype.call作为一种方法是如何工作的

Function.prototype.call.call.call(my, this, "Hello3"); // output 'Hello3'
我无法解释JavaScript解释器如何解释上述语句?从右到左解读“呼叫”?那么我的(Function.prototype.call.call)是什么意思

为什么我可以在这里放置任意数量的“.call”,并且输出是相同的?不是每个调用都使用一个参数作为“this”对象,这意味着只有三个参数是不够的吗?与上一个问题类似的问题

还有更多的例子:

function my(p) { console.log(p) }
Function.prototype.call.call(my, this, "Hello"); // output 'Hello'
var $ = Function.prototype.call
$(my, this, 'Hello5') // Exception: TypeError: Function.prototype.call called on incompatible Proxy
为什么它不输出任何东西,就像上面的一个例子

var v = Function.prototype.call.call 
v(my, this, 'Hello6') // Exception: TypeError: Function.prototype.call called on incompatible Proxy
这是否意味着,当使用变量v时,JavaScript解释器试图孤立地解释v,而没有看到后面有参数?那么解释器认为'this'是全局变量'window'?我不知道v()和Function.prototype.call.call()之间的解释器如何工作


有人能帮忙吗?谢谢

Function.prototype.call.call(我的,这是“你好”)表示:

my
用作
这个
参数(函数上下文),用于
call
ed函数。在这种情况下,调用了
function.prototype.call

因此,
Function.prototype.call
将以
my
作为上下文进行调用。这基本上意味着-它将是要调用的函数

将使用以下参数调用它:
(this,“Hello”)
,其中
this
是要在要调用的函数中设置的上下文(在本例中,它是
my
),要传递的唯一参数是
“Hello”
字符串

只要您的
my
函数没有以任何方式使用
上下文,您就可以传递任何内容:

Function.prototype.call.call(my, 123, 'Hello2') // outputs "Hello2"

只要
Function.prototype.call.call
引用与
Function.prototype.call.call
(和
Function.call
my.call
)相同的函数,您就可以添加任意数量的
。call
属性访问,并且不会更改任何内容

关于你的第二个问题:

var $ = Function.prototype.call
$(my, this, 'Hello5')
不起作用,因为函数调用的上下文是在调用过程中动态设置的(除非它与
.bind()
绑定或是ES2015 arrow函数)


因此,当您将其作为
$
调用时,上下文不会显式设置(因为它是变量,而不是对象),因此默认情况下,它会设置为
未定义的
或全局对象(取决于您运行代码的方式)。

每个对象都链接到原型对象。当试图检索对象上不存在的属性时,将查找其原型对象。

这是JavaScript函数中可用的一个特殊变量。它的值取决于调用函数的方式,而不是定义函数的方式(有些例外)


如您所见,在
Function.prototype
上定义了,这意味着所有函数对象都可以访问它。它是一个特殊的函数,因为它允许您在调用函数时显式设置
this
的值

一种常见用法是在类似数组的对象上调用数组函数,这些对象不是从
数组继承的。prototype

function f(){
    const args = Array.prototype.slice.call( arguments );
    // `args` is now a real array with all the privileged functions.
}

回到你的例子

function my(p) { console.log(p) }
Function.prototype.call.call(my, this, "Hello"); // output 'Hello'
这里您正在调用
Function.prototype.call
上的
call

它相当于

function my(p) { console.log(p) }
my.call(this, "Hello"); // output 'Hello'
由于
call
是在
Function.prototype
上定义的,并且它本身就是一个函数,因此当您调用
call
两次时,您正在检索相同的函数。这就是为什么你可以无限期地将它们链接起来

函数my(p){console.log(p)}
const call1=Function.prototype.call;
const call2=Function.prototype.call.call;//与“call1.call”相同。
const call3=my.call;
console.log(call1==call2);

console.log(call1==call3)我很难回答这个问题,因为从精神上讲,我很难从“this”这个参数跳出来,这个参数被视为调用方法的伪对象。我总结了我的理解(在Nodejs中):

使用的参考资料:


Function.prototype.call.call==Function.prototype.call//true
Function.call===Function.prototype.call.call//true
谢谢。是的,它们是严格相等的,但是你能解释一下,当它们后面有相同的参数时,为什么它们的输出是不同的吗?我在回答中没有这样做吗?当我调用函数变量时,为什么JavaScript解释器不将$转换为function.prototype.call.call,然后看$后面是括号内的一个对象?它可以通过这种方式找到“this”对象。所以我仍然不知道函数在这里是如何执行的,因为标准告诉解释器是如何工作的:上下文是在函数调用期间确定的。而且,
$(…)
没有任何上下文。我应该参考ECMA-262吗?如果有的话,请问是哪一部分?我不是
function f(a) {console.log(a);}

f.call(global, 1);
//function reference to be called = f
//context to call it from = global
//parameters used when invoking = 1
//equivalent call => global.f(1)

Function.prototype.call.call(f, global, 1);
//function reference to be called = Function.prototype.call
//context to call it from = f
//parameters used when invoking = global, 1
//equivalent call => f.call(global, 1)