我已经在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解释器如何解释上述语句?从右到左解释“call”?那么我的.(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()的解释器有什么不同。
有人能帮帮忙吗?谢谢!
发布于 2017-04-15 17:25:59
Function.prototype.call.call(my, this, "Hello");的意思是:
使用my作为经过call编辑的函数的this参数(函数上下文)。在本例中,调用了Function.prototype.call。
因此,将使用my作为其上下文来调用Function.prototype.call。这基本上意味着-它将是要调用的函数。
它将使用以下参数调用:(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()或者是一个ES2015箭头函数)。
因此,当您将其作为$调用时,上下文没有显式设置(因为它是一个变量,而不是一个对象),所以在默认情况下,它被设置为undefined或全局对象(取决于您运行代码的方式)。
发布于 2017-04-18 22:01:05
每个对象都链接到一个原型对象。当尝试检索对象上不存在的属性时,将查找其原型对象。Read more。
this是JavaScript函数中提供的特殊变量。它的值取决于调用函数的方式,而不是定义函数的方式(有一些例外)。Read more。
正如您所看到的,call是在Function.prototype上定义的,这意味着所有函数对象都可以访问它。它是一个特殊的函数,因为它允许您在调用函数时显式设置this的值。
一种常见的用法是在类似数组的对象上调用数组函数,这些对象不是从Array.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时,您将检索到相同的函数。这就是为什么你可以无限期地链接它们。
function my(p) { console.log(p) }
const call1 = Function.prototype.call;
const call2 = Function.prototype.call.call; // Same as `call1.call`.
const call3 = my.call;
console.log( call1 === call2 );
console.log( call1 === call3 );
现在来看问题的第二部分。this是如何在函数中工作的。Read more。
要记住的是,它的值是动态确定的,基于您调用函数的方式,而不是您如何定义它的(有一些例外)。
这样做时,call函数的this值将是当前作用域中的任何值(在全局作用域中,它在严格模式下为undefined,在window·中为window)。
var v = Function.prototype.call.call
v(my, this, 'Hello6') // Exception: TypeError: Function.prototype.call called on incompatible Proxy这就是为什么你会收到这个错误,正如call所期望的那样,this不是一个函数。当您从对象调用函数时,this将引用该对象,这就是当您在某些函数上调用call时发生的情况(函数也是对象)。
发布于 2020-01-01 16:46:54
我纠结于这个问题,因为我在精神上很难从' this‘这个参数中跳出来,这个参数然后被视为调用方法所在的伪对象。我总结了我的理解(在Nodejs中):
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)使用的引用:
A shorthand for Function.prototype.call.call?
Javascript Function.prototype.call()
https://stackoverflow.com/questions/43424141
复制相似问题