一个在JavaScript中支持“模式匹配技术”的Babel插件

【一个在JavaScript中支持“模式匹配技术”的Babel插件】模式匹配(pattern matching)是 lisp 、rust 、scala 、erlang 等语言中的常见语法,不过 JavaScript 一直未支持这个特性,虽然 tc39 早有相关的题案https://github.com/tc39/proposal-pattern-matching,不过目前进展缓慢,遂研发了一个Babel插件用于在JavaScript中支持模式匹配的语法
babel-plugin-proposal-pattern-matching
安装 使用 npm:

npm install --save-dev babel-plugin-proposal-pattern-matching

设置 .babelrc
{ "plugins": ["babel-plugin-proposal-pattern-matching"] }

一些演示 简单使用
import match from 'babel-plugin-proposal-pattern-matching/match' const fib = n=>match(n)( (v=1)=>1, (v=2)=>1, _=>fib(_-1)+fib(_-2) )console.log(fib(10)) // -> 55

直接返回一个函数,配合函数式编程
import match from 'babel-plugin-proposal-pattern-matching/match' const fib = fnmatch( (v = 1) => 1, (v = 2) => 1, _ => fib(_ - 1) + fib(_ - 2) )console.log(fib(10))// -> 55const arr = [1, 2, 3]console.log( arr.map( fnmatch( (v = 1) => 'one', (v = 2) => 'two', (v = 3) => 'three' ) ) )// -> [ 'one', 'two', 'three' ]

数据类型判断
import { match , T} from 'babel-plugin-proposal-pattern-matching/match'const getType = item => match(item)( (v = T.number) => 'number', (v = T.string) => 'string', (v = T.nullish) => 'nullish', _ => `${_} undefined type` )console.log(getType('a')) // -> stringconsole.log(getType(1)) // -> numberconsole.log(getType(undefined)) // -> nullishconsole.log(getType(null)) // -> nullish

实例判断
import { match, instanceOf } from 'babel-plugin-proposal-pattern-matching/match'const getType = val => match(val)( (v=instanceOf(RegExp))=>'RegExp', (v=instanceOf(Array))=>'Array', (v=instanceOf(Object))=>'Object', )console.log(getType(/111/)) // -> RegExp console.log(getType([1,2,3])) // -> Array console.log(getType({a:1})) // -> Object

解构,这里支持无限嵌套
import { match } from 'babel-plugin-proposal-pattern-matching/match' const sum = x => match(x)( ([x, ...xs]) => x + sum(xs), ([]) => 0 )console.log(sum([1, 2, 3])) // -> 6for (let i = 1; i <= 15; i++) { console.log( match({a: i % 3, b: i % 5})( ({a = 0, b = 0}) => 'FizzBuzz', ({a = 0, b}) => 'Fizz', ({a, b = 0}) => 'Buzz', _ => i ) ) } // -> // 1 // 2 // Fizz // 4 // Buzz // Fizz // 7 // 8 // Fizz // Buzz // 11 // Fizz // 13 // 14 // FizzBuzz

非运算
import { match, not, or, T } from 'babel-plugin-proposal-pattern-matching/match'const toNumber = n => match(n)( (v = not(T.boolean)) => v, (v = true) => 1, (v = false) => 0 )console.log( [true, false, 0, 1, 2, 3].map(toNumber) ) // -> [ 1, 0, 0, 1, 2, 3 ]

或运算
import { match, or } from 'babel-plugin-proposal-pattern-matching/match' const fib = n => match(n)( (v = or(1, 2)) => 1, _ => fib(_ - 1) + fib(_ - 2) )console.log(fib(10)) // -> 55

与运算
import { match, and, not } from 'babel-plugin-proposal-pattern-matching/match' const fib = n => match(n)( (_ = and(not(1), not(2))) => fib(_ - 1) + fib(_ - 2), _ => 1 )console.log(fib(10)) // -> 55

    推荐阅读