JavaScript 中的 (0, fn)(args) 语法
最近看 ts 看到一段这样的代码
示例,在 tsx 文件中
import { h } from "preact";
const HelloWorld = () => <div>Hello</div>;
经过 tsc 编译后的代码
const preact_1 = require("preact");
const HelloWorld = () => (0, preact_1.h)("div", null, "Hello");
这里 tsx 中的 <div> 写法只是一个语法糖,实际表示调用 h("div", null, "Hello")。
有意思的事情来了,明明可以是如 fn(args) 式的调用,生成的却是 (0, fn)(args) 式的调用。
为什么呢?
这里面蕴含的几个语法现象
逗号运算符对其每个操作数(从左到右)进行求值,并返回最后一个操作数的值。
let x = 1;
x = (x++, x);
console.log(x); // 2
x = (2, 3);
console.log(x); // 3
this指向
如下示例代码,由于逗号运算符的存在, (0, foo.sayName) 返回的是对 foo.sayName 这个函数的引用。然后函数执行时,其内部的 this 指向已经变为了全局的上下文。
var foo = {
fullName: "Peter",
sayName: function() {
console.log("My name is", this.fullName);
}
};
window.fullName = "Shiny";
foo.sayName(); // My name is Peter
(foo.sayName)(); // My name is Peter
(0, foo.sayName)(); // My name is Shiny
所以使用 (0, fn)(args) 的效果就是改变了函数 fn 内部的 this 指向,使其始终指向全局的上下文。
那么问题就变成了为什么要改变函数的 this 指向呢?
问了 deepseek ——
- 强制函数在全局上下文执行 - 切断原有的
this绑定- 避免意外的上下文绑定 - 确保函数行为可预测
- 代码压缩友好 - 比创建临时变量更简洁
- 函数式编程风格 - 强调"只是调用函数,不关心上下文"
总结一下,这种技巧在库函数、打包工具和框架代码中很常见,主要是为了确保函数的执行环境一致性。
参考