起因
事情的起因是这样的,最近在阅读style-loader源码时遇到这样一段代码:

难道我用的是假的JavaScript吗...
如果有大佬明白这么做的原因是为什么了...那么就可以停止阅读了。
分析
关于逗号操作符,在MDN上给出的是这样的解释:
逗号操作符 对它的每个操作数求值(从左到右),并返回最后一个操作数的值。
简单来说
代码语言:javascript复制const number = 1;
// 从左往右依次执行完毕后 返回最后一个值
number = (number , x);
console.log(number);
// expected output: 2
x = (2, 3);
console.log(x);
// expected output: 3上述代码的number = (number , x);其实就相当于number 而已。
可能有的同学有疑问了,这样做的效果是什么呢?
单纯为了秀而秀嘛!,别着急我们接下来往下看另外一个例子:
代码语言:javascript复制window.name = 'wang.haoyu'
const obj = {
name:'19Qingfeng',
logName() {
console.log(this.name)
}
}
obj.logName();
(0, obj.logName)();因为用到了
window对象,所以不要放在Node环境下执行这段代码。最简单的方式,直接将这段代码复制丢到
chrome控制台下去执行就ok了!
在丢到控制台之前,大家可以自己先来尝试自己思考一下两次分别的打印结果。

我们可以看到
**obj.logName()打印出19Qingfeng而(0, obj.logName)()打印出了全局对象上的window.name的wang.haoyu**。
两次打印结果不同的本质原因--函数调用时的this对象指向不同,第一次不用多说指向obj对象自然而然通过this.name打印出的就是19Qingfeg。
第二次(0, obj.logName)();执行机制是这样的:
- 首先逗号操作符的原因,**它会对于左边括号内从左往右求值,最终返回最右边的值也就是返回
obj.logName函数内容。 - 之后右侧的函数调用会调用左侧返回的
logName()函数,但是此时相当于直接调用logName()函数体自然而然this就指向了window上。
(0, obj.logName)();
// 本质上它就相当于这样
// 1. 通过逗号操作符获得函数内容
const tem = obj.logName
// 2. 外部调用修改调用者 同时改变this指向
tem()本质上我们可以通过逗号操作符修改函数内部this指向的改变,类似于call方法的效果。是不是很神奇!
结尾
其实在babel编译后的js代码中,包括许多源码中都会出现(0,parent.fn)()的方式。
一个小小的逗号操作符竟然能修改this指向,不得不说js真的是无奇不有。
希望这个知识点无论是在源码阅读中,还是面试交(吹)流(水)中都可以帮到大家脱口而出逗号操作符是可以改变函数执行时this指向为全局对象的!。


