有这样一道 JS面试题,问 fn.call.call.call.call(fn2)
的结果是什么?
先说下 call 函数的内部原理:
- 可以改变函数的this;
- 执行函数
下面模拟下 原生的call函数:
Function.prototype.call = function(context, ...args){context = context? Object(context) : window;// 改变 this context.fn = this;// 执行函数return context.fn(...args);
}
如下:
function fn(){console.log(11)
}function fn2(){console.log(22)
}
问:
fn.call.call.call.call(fn2) 的结果是什么?
解析:
- 前面的一串
fn.call.call.call.call
并没有调用,只是获取对象的call属性,所以,这一串的结果是 Function.call 属性。 - 所以那一串 就是
Function.call.call(fn2)
;还可以解理为 fn3.call(fn2)。 - 根据call的原理(可参考上面的call模拟),在 fn3执行call,其实际是这样执行的
fn2.fn3()
。 - 由于 fn3实际上就是 call 函数,所以, fn2.fn3() 等价于
fn2.call()
。 - 所以,上面那一串代码的最终结果,就是调用 fn2,所以结果输出 22.