使用Array.map结合call/apply调用trim时出现异常的原因咨询
call/apply给map会报错? 核心原因是函数的this绑定规则,拆解来看:
1. 直接传call/apply时的问题
当你写arr.map(String.prototype.trim.call),本质是把Function.prototype.call这个方法本身作为回调传给map,而不是trim函数。
map遍历数组时会调用这个回调(也就是call),但调用时不会给call绑定任何this值(严格模式下this为undefined,非严格模式是全局对象)。但call方法的正常运行,要求它的this必须指向一个函数——也就是你原本想调用的trim函数。
现在call的this是undefined,它找不到要执行的目标函数,自然抛出TypeError: undefined is not a function。
apply的情况完全一致:String.prototype.trim.apply是取了apply方法,map调用它时,apply的this是undefined,而apply需要this是一个函数,因此报错“在undefined上调用了apply”。
2. 箭头函数包裹为什么正常?
比如arr.map(str => ''.trim.call(str)),这里''.trim.call(str)是直接调用call方法:此时call是作为''.trim(即String.prototype.trim)的方法被调用的,所以call内部的this会自动绑定到trim函数上。
随后你把str作为call的第一个参数,相当于给trim函数绑定了this为str,最终trim能正常执行,完成字符串修剪。
替代写法:用bind固定this
如果不想用箭头函数,也可以通过bind把call的this固定为trim函数:
arr.map(Function.prototype.call.bind(String.prototype.trim));
这样map调用call时,call的this始终是trim,当前数组元素会作为call的第一个参数传递,效果和箭头函数一致。
内容的提问来源于stack exchange,提问作者Zorzi

