gpt4 book ai didi

javascript - Function.call、Function.prototype.call、Function.prototype.call.call 和 Function.prototype.call.call.call 之间的区别

转载 作者:太空宇宙 更新时间:2023-11-04 15:47:38 32 4
gpt4 key购买 nike

我在stackoverflow上查过很多类似的问题,比如call.call 1 , call.call 2 ,但我是新人,无法发表任何评论。我希望我能找到关于 JavaScript 解释器如何执行这些函数的全面而透彻的解释,并在这里提出一个新问题。

以下是一些示例:

function my(p) { console.log(p) }
Function.prototype.call.call(my, this, "Hello"); // output 'Hello'

上面的例子是Function.prototype.call的标准用法,比较容易理解。我的理解是:“my”作为函数对象执行其继承的方法“Function.prototype.call”,即。 my.(Function.prototype.call) => my.call(this, 'Hello')

Function.call.call(my, this, "Hello") // output '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 解释器如何解释上述语句?从右到左解释“调用”?那么 my.(Function.prototype.call.call) 是什么意思?

Function.prototype.call.call.call.call(my, this, "Hello4"); // output 'Hello4'

为什么我可以在这里输入任意数量的“.call”,而输出却是一样的?是否每个调用都会消耗一个参数作为“this”对象,这意味着只有三个参数是不够的?与上面的问题类似的问题

然后是更多示例:

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, this, "Hello"); 表示:

使用my作为call函数的this参数(函数上下文)。在本例中,Function.prototype.call 被调用。

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

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

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

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

一旦 Function.prototype.call.call 引用与 Function.prototype.call.call.call 相同的函数(并且 Function.call my.call)等等,您可以根据需要添加任意数量的 .call 属性访问,并且不会改变任何内容。

至于你的第二个问题:

var $ = Function.prototype.call
$(my, this, 'Hello5')

不起作用,因为函数调用的上下文是在调用期间动态设置的(除非它与 .bind() 绑定(bind)或者是 ES2015 箭头函数)。

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

关于javascript - Function.call、Function.prototype.call、Function.prototype.call.call 和 Function.prototype.call.call.call 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43424141/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com