首先需要了解apply,call的基本用法,其目的是改变调用方法中的this指向,将其指向为传入的对象
代码:console.log
- var console = window.console || {log: function () {}};
- var log = console.log;
- console.log = function(tips,message){
- Function.prototype.apply.call(log, console, arguments);
- //Function.prototype.call.call(log, console, arguments);
- //Function.prototype.call.apply(log, [console, arguments]);
- //传统方式
- //var args=[].slice.call(arguments);
- //log.apply(console,args);
- }
执行结果:
- console.log("测试","This is test");
- 测试 This is test
分析:
该怎么理解Function.prototype.apply.call(log,console,arguments);呢
首先可以将Function.prototype.apply看成一个整体-->FunctionApply
FunctionApply.call(log,console,arguments);
那么将此句翻译一下
log.FunctionApply(console,arguments);
然后再翻译一下,你就懂了吧,就是一个普通方法调用了
console.log(arguments);
发散思维:
Function.prototype.call.apply(log,[console.arguments]);
- FunctionCall.apply(log,[console,arguments]);
- log.FunctionCall(console,arguments);
- console.log(arguments);
小tips:
Function.prototype.apply.call 等同于Function.prototype.call.call
Function.prototype.call.apply 等同于 Function.prototype.apply.apply
免费外送个栗子:
- function testA(a){
- console.log('aaaa',a);
- }
- Function.prototype.apply.call(testA,window,['Mike']);
- //Function.prototype.call.call(testA,window,['Mike']);
- //testA.apply(window,['Mike']);
- //window.testA('Mike');
- //Function.prototype.apply.apply(testA,[window,['Mike']]);
- //Function.prototype.call.apply(testA,[window,['Mike']]);
以上执行结果都一样
为:aaaa Mike
总结使用用法:
XXX可以是call或者是apply,child一定是parent可指向的对象
Function.prototype.XXX.call(child,parent,arguments||array);
Function.prototype.XXX.apply(child,[parent,arguments||array]);
-------------------------------------------------------------------------------终极方法
Function.prototype.apply.call(console.log,console,arguments);
这么一对比,第三种方案妥妥的胜出啊,不用考虑兼容,代码简短,虽然不是很好理解~~
说了这么多废话,Function.prototype.apply.call什么时候用,就是在这种应用场景。
如果还有其他的话,那就是那些奇葩面试题,比如:
var f1=function(){console.log(1)};
var f2=function(){console.log(2)};
Function.prototype.call.call(Function.prototype.call,f2)//2
Function.prototype.call.call(f1,f2);//1
分析步骤如下: 1、将Function.prototype.call当成整体,call方法是由浏览器实现的本地方法,是函数类型的内部方法 var a = (Function.prototype.call).apply(function(a){return a;}, [0,4,3]);
2、fun.apply(obj,args)等价于obj.fun(args),这一步是重点,必须理解! (function(a){return a;}).apply(0,[4,3]) (function(a){return a;}).call(0,4,3)
3、 到这步结果就很明显了,a就是4,alert的结果就是4
这个题目迷惑的点就在于Function.prototype.call,理解好了,就清晰明了了!
转载:http://zhangzhaoaaa.iteye.com/blog/2246733