在 bluebird wiki article about JavaScript optimization killers ,作者提到将 arguments
关键字传递给任何函数(apply
除外)都会导致父函数不可优化。我想创建一个sweet.js宏允许我编写标准惯用的 JavaScript,但会处理优化 killer 。
理想情况下,我想要一个具有以下功能的宏:
function foo() {
var args = [].slice.call(arguments);
return args;
}
并输出如下内容:
function foo() {
var args = [];
for(var i, len = arguments.length; i < len; i++) {
args.push(arguments[i]);
}
return args;
}
但是,我无法正确获取 sweet.js 宏语法。 This is what I have so far :
示例.sjs
let arguments = macro {
rule infix {
[].slice.call |
} => {
[];
for(var i = 0, len = arguments.length; i < len; i++) {
args.push(arguments[i])
}
}
}
function toArray() {
var args = [].slice.call arguments
return args;
}
输出如下:
function toArray() {
var args$2 = [];
for (var i = 0, len = arguments.length; i < len; i++) {
args.push(arguments[i]);
}
return args$2;
}
我尝试让我的宏在 arguments
关键字周围加上括号,并包含 var
声明,但没有成功。我尝试过这样的事情:
无效的宏
let arguments = macro {
rule infix {
var $var = [].slice.call ( | )
} => {
var $var = [];
for(var i = 0, len = arguments.length; i < len; i++) {
args.push(arguments[i])
}
}
}
这会产生以下错误:
SyntaxError: [syntaxCase] Infix macros require a `|` separator
414:
^
最佳答案
是的,有几种方法可以做到这一点。提出论点
括号内部不起作用,因为中缀宏无法与外部匹配
包含分隔符,因此当 arguments
宏被调用时
在它之前或之后看到零个标记(错误应该更清楚)。
您的另一个解决方案遇到了卫生问题,因为
arguments
宏需要访问 args
标识符,但需要中缀
当宏位于等号之前时不允许匹配
var
语句,因此它实际上无法匹配 args
标识符。
有几个解决方案。最简单的就是做类似的事情 bluebird 维基建议:
macro argify {
rule { ( $arg ) } => {
var $arg;
for (var i, len = arguments.length; i < len; i++) {
args.push(arguments[i]);
}
}
}
function foo() {
argify(args)
return args;
}
你也可以走不卫生的路线(不真正推荐,但
arguments
已经有点不卫生了,所以……):
let function = macro {
case {$mname $name ( $parens ...) { $body ... } } => {
letstx $args = [makeIdent("args", #{$mname})];
return #{
function $name ( $parens ...) {
var $args = [];
for (var i, len = arguments.length; i < len; i++) {
$args.push(arguments[i]);
}
$body ...
}
}
}
}
function foo() {
return args;
}
编辑:
我只是想到了另一种解决方案,它允许您通过覆盖 var
来保留当前语法:
let var = macro {
rule { $args = [].slice.call(arguments) } => {
var $args = [];
for(var i, len = arguments.length; i < len; i++) {
$args.push(arguments[i]);
}
}
rule { $rest ... } => { var $rest ... }
}
function foo() {
var args = [].slice.call(arguments);
}
关于javascript - 如何在 sweet.js 中创建参数化中缀宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26555614/