ES Levels

By default, Ruby2JS will output JavaScript with the widest compatibility possible, but that also means many new features in recent ECMAScript versions are compromised or impossible to achieve.

By passing an eslevel option to the convert method, you can indicate which new language features you wish to enable. Every newer level enables older levels, so for example 2021 will enable ES2015, ES2016, etc.

ES2015 support

When option eslevel: 2015 is provided, the following additional conversions are made:

  • "#{a}" `${a}`
  • a = 1 let a = 1
  • A = 1 const A = 1
  • a, b = b, a [a, b] = [b, a]
  • a, (foo, *bar) = x let [a, [foo, ...bar]] = x
  • def f(a, (foo, *bar)) function f(a, [foo, ...bar])
  • def a(b=1) function a(b=1)
  • def a(*b) function a(...b)
  • .each_value for (i of ...) {}
  • a(*b) a(...b)
  • "#{a}" \`${a}\`
  • lambda {|x| x} (x) => {return x}
  • proc {|x| x} (x) => {x}
  • a {|x|} a((x) => {})
  • class Person; end class Person {}
  • Class.new do; end class {}
  • (0...a).to_a [...Array(a).keys()]
  • (0..a).to_a [...Array(a+1).keys()]
  • (b..a).to_a Array.from({length: (a-b+1)}, (_, idx) => idx+b)

ES2015 class support includes constructors, super, methods, class methods, instance methods, instance variables, class variables, getters, setters, attr_accessor, attr_reader, attr_writer, etc.

Additionally, the functions filter will provide the following conversion:

  • Array(x) Array.from(x)
  • .inject(n) {} .reduce(() => {}, n)

Keyword arguments and optional keyword arguments will be mapped to parameter destructuring.

Classes defined with a method_missing method will emit a Proxy object for each instance that will forward calls. Note that in order to forward arguments, this proxy will return a function that will need to be called, making it impossible to proxy attributes/getters. As a special accommodation, if the method_missing method is defined to only accept a single parameter it will be called with only the method name, and it is free to return either values or functions.

ES2016 support

When option eslevel: 2016 is provided, the following additional conversion is made:

  • a ** b a ** b

Additionally the following conversions is added to the functions filter:

  • .include? .includes

ES2017 support

When option eslevel: 2017 is provided, the following additional conversions are made by the functions filter:

  • .values() Object.values()
  • .entries() Object.entries()
  • .each_pair {} for (let [key, value] of Object.entries()) {}
  • include M Object.defineProperties(..., Object.getOwnPropertyDescriptors(M))

async support:

  • async def async function
  • async lambda async =>
  • async proc async =>
  • async -> async =>
  • foo bar, async do...end foo(bar, async () => {})

ES2018 support

When option eslevel: 2018 is provided, the following additional conversion is made by the functions filter:

  • .merge {...a, ...b}

Additionally, rest arguments can now be used with keyword arguments and optional keyword arguments.

ES2019 support

When option eslevel: 2019 is provided, the following additional conversion is made by the functions filter:

  • .flatten .flat(Infinity)
  • .lstrip .trimEnd
  • .rstrip .trimStart
  • a.to_h Object.fromEntries(a)
  • Hash[a] Object.fromEntries(a)

Additionally, rescue without a variable will map to catch without a variable.

ES2020 support

When option eslevel: 2020 is provided, the following additional conversions are made:

  • a&.b a?.b
  • .scan Array.from(str.matchAll(/.../g), s => s.slice(1))

ES2021 support

When option eslevel: 2021 is provided, the following additional conversions are made:

  • x ||= 1 x ||= 1
  • x &&= 1 x &&= 1
  • 1000000.000001 1_000_000.000_001
  • '.gsub' <sl-icon name="caret-right-fill"></sl-icon> .replaceAll`

ES2022 support

  • @x this.#x (unless the underscored_private option is set to true)
  • @@x ClassName.#x
  • self.a = [] static a = [] (within a class)

When the filter function is enabled, the following additional conversions are made:

  • x[-2] x.at(-2)
  • x.last x.at(-1)

Next: Community