(0 , function)(param) 究竟是什么?
最近在读一些 loader 的源码,发现有许多摸不着头脑的地方,其中一点是有许多函数在调用时,都采用了(0, function)(param)
的形式调用。如
(0, _schemaUtils.default)(_options.default, options, {
name: 'CSS Loader',
baseDataPath: 'options'
});
网上资料
刚开始很不理解,在 stackoverflow 上寻找答案,大致了解这种写法的作用是强制改变 this 的指向。
What is the meaning of this code (0, function) in javascript [duplicate]
有几种说法,不过基本上可以理解为改变了 this 的指向。
实践出真知
那么它的 this 指向究竟被改成了啥?带着这个疑问,写下如下代码并在两种环境下运行(node / window)
function outerFunc(outerParam) {
console.log(outerParam);
console.log(this);
function middleFunc(middleParam) {
console.log(middleParam);
console.log(this);
function innerFunc(innerParam) {
console.log(innerParam);
console.log(this);
}
(0, innerFunc)('我是内部函数');
}
(0, middleFunc)('我是中部函数');
}
(0 , outerFunc)('我是外部函数');
node
我是外部函数
Object [global]
我是中部函数
Object [global]
我是内部函数
Object [global]
window
原来如此,(0, function)(param)
会将 this 指向调用堆栈的最底层,也就是 window 或者 global。
而且有趣的是,不光是 0 ,你传随意值,0可能是为了理解和方便。
事后反思
为什么源码要用这种 (0, function)(param)
方式去绑定 this,而不是 function.call()/apply()
的形式呢?
那是因为这些源码中有时会修改 prototype
,将 call/apply
指向成自己的函数,甚至改变prototype
的指向,这样就会导致原型链上方法不可用,那就只好(0, function)(param )
了。我理解这有点亡羊补牢的感觉。。。
了解一下就好了,实际开发中还是不要修改原型链,避开使用这种小众化的语法。
不得不说,源码真让人摸不着头脑