前言
为什么很多 vue,react 等项目后打包后会出现 (0, function)(args) 这种语法?这是因为打包工具比如 webpack 中会使用 babel 代码转换工具,这行代码就是 babel 在转换 es6 模块语法时输出的。
使用 babel 转换 es6 模块
- 转换前
print.js
export default function print(num){
console.log('print fuc', 1)
}
index.js
import print from "./print";
print(1)
- 使用转换命令:./node_modules/.bin/babel src --out-dir lib
- 转换后的代码
print.js
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = print;
function print(num) {
console.log('print fuc', 1);
}
index.js
"use strict";
var _print = _interopRequireDefault(require("./print"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
(0, _print.default)(1); // <=== 逗号操作符
什么是逗号操作符
逗号操作符对它的每个操作数求值(从左到右),并返回最后一个操作数的值。当你想要在期望一个表达式的位置包含多个表达式时,可以使用逗号操作符。
let val = 1
let res = (++val, ++val) // val =3, res = 3
上面代码可以理解为
let val = 1
let temp = ++val
temp = ++val
let res = temp
改变 this 指向
假如不使用逗号操作符,那么直接调用
_print.default() // this 指向 _print 对象
从代码结构上看,这是不符合函数的执行环境的。
根据上面介绍,现在我们可以知道
(0, _print.default)(1);
等价于
let temp = 0
temp = _print.default
temp(1)
把函数赋值给 temp,再调用函数,相当于改变了函数的对象,所以 this 指向从 _print 改变成 undefined(strict 模式下),假如是非 strict 模式,那么 this 指向 global 或 window,这样才符合函数的执行环境。