Javascript Can';t直接使用Function.prototype.call
为什么最后一行返回未定义的,我认为它们是一样的 这些将是相同的:Javascript Can';t直接使用Function.prototype.call,javascript,Javascript,为什么最后一行返回未定义的,我认为它们是一样的 这些将是相同的: 函数f(a){返回a} console.log(f(1));//=>1. console.log(f.call(null,1));//=>1. console.log(Function.prototype.call.call(f,null,1));//=>1让我们从以下内容开始: function f(a) { return a} f(1) // => 1 f.call(null, 1) // => 1 Fun
函数f(a){返回a}
console.log(f(1));//=>1.
console.log(f.call(null,1));//=>1.
console.log(Function.prototype.call.call(f,null,1));//=>1
让我们从以下内容开始:
function f(a) { return a}
f(1) // => 1
f.call(null, 1) // => 1
Function.prototype.call(f, null, 1) // => undefined
因此,让我们深入挖掘并尝试实现一个伪调用
函数:
function fn() { console.log(this); }
fn.a = function(){console.log(this)}
fn.a() // function fn() { console.log(this); }
因此,当我们这样做时:Function.prototype.fakeCall.fakeCall(a,obj,'hi')
发生的情况是,在第一次运行时,我们有:
arr=[obj,'hi']
this=Function.fakeCall
Function.fakeCall.apply(a[obj,'hi'])代码>
然后在第二轮我们有
arr=['hi']
this=a
因此我们最终得到了a.apply(obj,['hi'])
,这与a.call(obj,['hi')相同代码>
然而,如果我们做了Function.fakeCall(a,obj,'hi')代码>
在第一次运行时,我们将使用this=Function
,但这不会起作用。在这种情况下,它将抛出一个错误,在您的情况下,它只返回undefined。这可以通过try catch
轻松实现
Function.prototype.fakeCall = function () {
// console.log(this)
// taking the arguments after the first one
let arr = Array.prototype.slice.call(arguments, 1);
// on the first run this will be Function.fakeCall but on the second pass it will be the first argument (the a function)
this.apply(arguments[0], arr);
}
function a(ar){ console.log(ar + this.name) };
let obj = {name : "thierry"};
// a.fakeCall( obj, 'hi ')
Function.fakeCall.fakeCall(a, obj, 'hi ');
Function.prototype.call.call(f,null,1)
您现在正在做的是var fp=Function.prototype;fp.call(f,null,1)
和fp.call(…)
与f.call(…)
不同。这些只是不同的功能。谢谢你们的快速依赖,这是一个头脑stretcher@mko如果您检查我的答案,我将不胜感激。我不认为当前的答案,也不认为他链接的答案能够很好地回答这个问题。不过这只是我的意见。@mko我更新了我的答案,以便根据Function.prototype.call的实际工作原理,对Function.prototype.call
和Function.prototype.call.call
之间的区别给出一个易于理解的解释。希望能帮上忙…我需要一些咖啡来解决这个问题,谢谢你的解释风格教我更多关于潜在机制的知识。非常感谢。
Function.prototype.fakeCall = function () {
let arr = Array.prototype.slice.call(arguments, 1);
try{
return this.apply(arguments[0], arr);
}catch(e){}
}
function a(ar){ return ar + this.name };
let obj = {name : "thierry"};
console.log(Function.fakeCall(a, obj, 'hi ')); // undefined
console.log(Function.fakeCall.fakeCall(a, obj, 'hi ')); // hi thierry