JavaScript回调疑问:为何直接传window.location.toString()无效?
window.location.toString不能正常工作? 嘿,这个问题的核心其实是函数引用传递和JavaScript中this的绑定规则在搞鬼,咱们一步步拆解清楚:
先看正常工作的场景
当你传递getLocation或者anyOther给myFunc的func参数时,你传递的是函数本身的引用。当myFunc里调用func()时,这些普通函数的this在非严格模式下默认绑定到window,所以getLocation里的window.location.toString()能正常访问到正确的对象,自然输出没问题。
再看出问题的window.location.toString
这里你传递的是location对象上的toString方法的引用,但这个方法的正常运行依赖于this指向window.location这个实例。当myFunc里调用func()时,此时func(也就是这个toString方法)的this被默认绑定到了window,而不是原来的location对象。
很多内置对象的方法都对this的指向有要求,location.toString必须让this指向location才能正确返回当前URL,一旦this变成window,它就无法获取到location的相关信息,自然就不能正常工作了。
额外说下:直接传window.location.toString()会怎么样?
如果你直接写myFunc("From", window.location.toString()),这时候你不是传递函数引用,而是先执行了这个方法,把执行后的返回值(当前URL字符串)传给了func参数。当myFunc里尝试调用func()时,就会报错——因为字符串不是函数,没法执行调用操作。
解决办法
你已经用到了一种:把它包在一个自定义函数里,比如:
function getLocation() { return window.location.toString(); }
或者更简洁的箭头函数(箭头函数的this继承自外层作用域,这里就是window,所以能正常访问window.location):
myFunc("From", () => window.location.toString());
另一种方法是用bind固定this指向:
myFunc("From", window.location.toString.bind(window.location));
这样传递的toString方法会把this永久绑定到window.location,调用时就能正常返回URL了。
内容的提问来源于stack exchange,提问作者Panos K

