1 回答
TA贡献1829条经验 获得超13个赞
要理解这个需要深入理解javascript中函数内置方法call, apply等的运作机制,我们从简单的开始吧:
1 首先,我们知道call或apply的第一个参数是context, 我们来试验一下:
| 12345 | function test() { console.log(this.valueOf());}test.call(); // window / global contexttest.call(2);// 2 |
这一步很好理解吧?
那么,我们变换一下,把call提出来:
var call = test.call; call === test.call // truecall(); //TypeError: object is not a functioncall(2); //TypeError: object is not a function |
可以看到,call还是那个call, 但是却出错了,这告诉我们什么呢? 原来call或apply内部是直接将this做为一个函数进行调用(当然是对该函数进行了上下文绑定的)。
2 有了前面的认识,理解你这个问题就简单多了
首先,func.call.call.call(func2, func3, func4) ,其实无论有多少个.call, 最终都等价于
func.call.call(func2, func3, func4)
即等价于 Function.prototype.call.call(func2, func3, func4)
我们主要来分析下 func.call.call(func2, func3, func4)执行
a. func.call.call(func2, func3, func4)
为了便于理解,我们做个变换, 使上面的调用等价于如下过程
| 12 | var test = func.call;test.call(func2, func3, func4) |
这个很好理解,就是以func2为context执行test函数,并传入参数func3, func4
b. 执行test函数时的特殊性
执行test函数时发生了一个很有趣的事,test实际是func.call函数也就是Function.prototype.call函数,由第1节我们知道,这个函数的作用是将this(也就是它的context)做为一个函数进行调用,由于a中test的context被设为了func2, 所以执行test函数的结果实际是执行了func2函数,并且由于call函数的作用,在调用func2时,它会将func3做为func2的context, 并向func2传入一个参数就是func4.
也就是这样:
| 1 | func2.call(func3, func4) |
OK, 因此你的两个调用: func.call.call.call(func2,func3,func4), func.call.call(func2,func3, func4) 最终都等价于
func2.call(func3, func4)
可以看到,func实际点作用都没,哦,不,唯一的作用就是引入call函数, 所以有些人也写成这样:
| 1 | Function.call.call(xxx,xx,xx); |
添加回答
举报
