ECMAScript语法提案 智能管道运算符(smart pipelines)
这是一个充满了函数式编程,艺术感和逼格的语法(合理利用可以有效劝退初学者和其他语言想转js的同学,减少js程序员竞争激烈程度。。。) 详情请看proposal-smart-pipelines
核心提案
中缀管道运算符... |> ...
与#
词法
babel 7已经支持了中缀|>
运算符(不过是另一个pipelines提案),#
目前暂未被实现
|>
运算符用来让层层嵌套的函数调用变得易读和易写
Math.sqrt(Math.sqrt(81)); // 3
81 |> Math.sqrt |> Math.sqrt; // 3
function div2(num) { return num / 2; }
// 像这样的调用不用管道运算符写起来会(十(分(难(受))));
1024
|> div2
|> div2
|> div2
|> div2
|> div2; // 32
通过以下例子可以很容易理解#
这个符号的作用。
2 |> # + 2; // 4
'hello' |> # + ' world'; // 'hello world'
// 可以写在各种各样的语句中
new Promise(resolve => resolve(123))
|> await #
|> new Foo(#)
|> bar(#)
|> baz(1, #, 2)
// |> yield #
|> # || throw new Error()
|> [#, # + 1, # + 2]
|> ({ arr: # }) // 像箭头函数返回对象时一样,这里也要用括号
|> #.arr
|> [...#]
|> (# => #.concat([1])); // 这里也必须使用括号
// console.log(
// Math.max(
// -(input - 3) * 2,
// 0
// )
// );
input
|> # - 3
|> -#
|> # * 2
|> Math.max(#, 0)
|> console.log;
// # 是不可修改的
input |> (# = 1); // Error
通过|>
和#
两个符号,我们可以轻易地将嵌套多层函数调用拍平
出于代码可读性的原因,以下用法是被禁止的
// 高阶函数使用管道语法容易在阅读代码时混淆含义
input |> object.method(); // Error
// object.method()(input);
// object.method(input);
// 此时应使用#符号
input |> object.method()(#); // ok
// 声明函数和类,在管道中,即使像下例一样简单的函数声明也会变得很难还原出原意
value
|> processing
|> function (x = #) { return x; }; // Error
// 原意如下:
// function (x = processing(value)) {
// return x;
// }
// for/while/catch/with语句块同理
input
|> process
|> (x, y) => {
for (const element of #)
…
}
// (x, y) => {
// for (const element of process(input))
// …
// }
额外特性提案
以上是smart pipelines语法的核心提案部分,在此基础上还有一些额外的特性提案
Additional Feature BC (支持对象的构造器)
// '123'
// |> new Number(#);
'123'
|> new Number;
Additional Feature BA (支持异步函数)
async function foo(arg) { return arg; }
// 123
// |> await foo(#);
123
|> await foo;
Additional Feature BP (支持代码块)
它的表现类似于另一个提案 do-expression(事实上已经能够完全取代该语法了)。该代码块的最后一个表达式的值为代码块的值
123
|> {
console.log(#); // 123
# + 1;
}
|> #; // 124
Additional Feature PF (管道函数+>
)
邪能语法之一,让你能够在管道外的其他地方用上#
// [1, 2, 3].map(i => i * 2)
// [1, 2, 3].map(i => i |> # * 2)
[1, 2, 3].map(+> # * 2); // [2, 4, 6]
// 异步管道函数
const asyncPipelineFunction = async +>
|> await foo
|> bar;
Additional Feature TS (支持try-catch)
// let _1;
// try {
// _1 = 1 / f(value);
// }
// catch (error) {
// _1 = processError(error);
// }
// g (_1, 1);
value
|> f
|> {
try |> 1 / #;
catch |> processError;
}
|> g;
Additional Feature NP (多参数管道)
邪能语法之二…
function add(...args) { return args.reduce((a, b) => a + b, 0); }
(1, 2)
|> add(#, 4, ##); // 7
// ...会得到最后一个被使用的参数之后的所有参数
(1, 2, 4, 8)
|> add(##, ...); // 14
// 支持解构
(1, ...[2, 4, 8])
|> add(##, ...); // 14