On this page:
2.1 Racket  Script’s Java  Script FFI Primitive
#%js-ffi
2.2 Racket  Script’s Java  Script FFI API
$
$$
$/  new
$/  throw
$/  undefined
$/  null
$/  this
$/  arguments
$/  obj
$/  :  =
$/  array
$/  require
$/  require/  *
$>
$/  typeof
$/  instanceof
$/  binop
$/  +
js-string->string
js-string
$/  str
2.3 Reader Extensions
8.17.0.6

2 The RacketScript-JavaScript FFI🔗ℹ

 (require racketscript/interop)
  package: racketscript-compiler

RacketScript supports direct interoperability with most JavaScript features. This section explains how to invoke plain JavaScript in a RacketScript program.

2.1 RacketScript’s JavaScript FFI Primitive🔗ℹ

RacketScript’s #%js-ffi form compiles directly to various JavaScript features. The first argument is a symbol that indicates the kind of JavaScript code to be generated and the rest are the arguments for that kind of operation.

NOTE: Users most likely should not be using this form. Instead, use the API described in the RacketScript’s JavaScript FFI API section, which will expand to the appropriate call to #%js-ffi.

syntax

(#%js-ffi 'var)
(#%js-ffi 'ref obj prop-id)
(#%js-ffi 'index obj prop-expr)
(#%js-ffi 'assign x e)
(#%js-ffi 'new expr)
(#%js-ffi 'throw exn)
(#%js-ffi 'undefined)
(#%js-ffi 'null)
(#%js-ffi 'this)
(#%js-ffi 'arguments)
(#%js-ffi 'object [fld v] ...)
(#%js-ffi 'array args ...)
(#%js-ffi 'typeof obj)
(#%js-ffi 'instanceof obj type)
(#%js-ffi 'string str)
(#%js-ffi 'require mod)
(#%js-ffi 'operator 'op operand ...)

Summary of JavaScript operations supported by #%js-ffi:

  • 'var: Use to access variable in the JavaScript namespace

  • 'ref: JavaScript object property reference, i.e., dot notation

  • 'index: JavaScript index operation, i.e., bracket notation

  • 'assign: JavaScript assignment

  • 'new: JavaScript object constructor

  • 'throw: Throw JavaScript exception

  • 'undefined: JS undefined value

  • 'null: JS null object value

  • 'this: JS this object self reference

  • 'arguments: implicit JS arguments variable containing function args

  • 'object: JS object literals, i.e, curly brace notation

  • 'array: JS array literals, i.e, bracket notation

  • 'typeof: JS typeof operation

  • 'instanceof: JS instanceof operation

  • 'string: JS strings (incompatible with Racket/RacketScript strings, see $/str)

  • 'require: JS import, use to import JS libraries

  • 'operator: Use to call JS functions requiring infix notation

2.2 RacketScript’s JavaScript FFI API🔗ℹ

syntax

($ jsid)

($ expr sym)
($ expr expr)
($ expr expr ...)
 
jsid = valid JS identifier (alphanumeric underscore and dollar chars)
 
  sym : symbol?
Syntax for accessing Javascript variables and properties.

  • Using the $ operator with a single identifier references a JavaScript variable.

    Example: ($ JSON)

    Note: the identifier be a valid JavaScript identifier (underscore, dollar, and alphanumeric characters only), and not Racket or RacketScript one.

    Equivalent to (#%js-ffi 'var jsid).

  • Supplying a second argument that is a symbol corresponds to accessing a JavaScript object property using dot notation, where the symbol name is the property name.

    Example: If handling a web request named req, getting the body of the request could be written ($ req 'body) which compiles to req.body in JavaScript.

    Equivalent to (#%js-ffi 'ref req 'body).

    Note: The above assumes that req is a RacketScript variable. If the variable is in the JavaScript namespace only, then an additional $ is needed to first access the variable (see first $ case above).

    Example: ($ ($ JSON) 'parse) compiles to the JavaScript JSON.parse function.

    Equivalent to (#%js-ffi 'ref (#%js-ffi 'var JSON) 'parse).

  • A second argument that is an arbitrary expression is treated as JavaScript bracket notation.

    Example: ($ req "body") compiles to req["body"] in JavaScript.

    Equivalent to (#%js-ffi 'index req "body").

  • Supplying more than two arguments corresponds to a series of bracket lookups.

syntax

($$ dot-chain e ...)

 
dot-chain = symbol or identifier consisting of multiple dot-separated names
Shorthand for multiple $s. Allows more direct use of dot notation in RacketScript. E.g., ($$ window.document.write) corresponds to window.document.write in JavaScript.

syntax

($/new constructor-expr)

JavaScript object construction. Equivalent to (#%js-ffi 'new constructor-expr).

syntax

($/throw exn)

Throw a JavaScript exception. Equivalent to (#%js-ffi 'throw exn).
The JavaScript undefined value. Equivalent to (#%js-ffi 'undefined)

syntax

$/null

The JavaScript null object. Equivalent to (#%js-ffi 'null).

syntax

$/this

The JavaScript this keyword. Equivalent to (#%js-ffi 'this).
The JavaScript arguments object containing the arguments passed to a function. Equivalent to (#%js-ffi 'arguments).

syntax

($/obj [fld v] ...)

 
fld = identifier
JavaScript object literal notation, i.e., brace notation, where fld are identifiers representing the object’s properties, and v ... are values assigned to those properties. Equivalent to (#%js-ffi 'object fld ... v ...)

syntax

($/:= e v)

JavaScript assignment statement. Equivalent to (#%js-ffi 'assign e v). e should be a symbol, or a #%js-ffi 'var, 'ref, or 'index call.

syntax

($/array e ...)

JavaScript array literal notation, where ($/array 1 2 3) compiles to [1,2,3]. Equivalent to (#%js-ffi 'array e ...)

syntax

($/require mod)

($/require mod *)
 
  mod : string?
JavaScript import statement.

Often used with define, e.g., (define express ($/require "express")) compiles to:

import * as express from "express";

Equivalent to (#%js-ffi 'require mod) or (#%js-ffi 'require '* mod)

syntax

($/require/* mod)

 
  mod : string?
JavaScript import all statement.

Shorthand for ($/require mod *)

syntax

($> e call ...)

 
call = id
  | (meth arg ...)
JavaScript chaincall.

For example:

($> (#js.res.status 400) (send #js"Bad Request"))

is compiles to res.status(400).send("Bad Request")

Equivalent to nested #%js-ffi calls (with 'var, 'ref, or 'index).

syntax

($/typeof e)

($/typeof e type)
 
  type : 
(and/c string?
       (or/c "undefined" "object" "boolean" "number" "string" "function"))
JavaScript typeof operator.

The first form returns a string representing the typeof the given JavaScript value. Equivalent to (#%js-ffi 'typeof e).

The second form is shorthand for checking the type of a value. For example, ($/typeof 11 "number") is compiles to

typeof 11 === "number";

Equivalent to ($/binop === (#%js-ffi 'typeof e) ($/str v))

syntax

($/instanceof e type)

 
e = JavaScript Object
Returns a boolean indicating whether JavaScript object e is an instance of type.

Equivalent to (#%js-ffi 'instanceof e type)

syntax

($/binop op operand1 operand2)

JavaScript infix binary function call.

Equivalent to (#%js-ffi 'operator 'op operand1 operand2)

syntax

($/+ operand ...)

Multi-argument infix calls to JavaScript + (can be used as either concat or addition). Equivalent to multiple nested calls to $/binop.

procedure

(js-string->string jsstr)  string?

  jsstr : JSstring
Converts a JS string to a RacketScript string.

procedure

(js-string str)  JSstring

  str : string?
Converts a RacketScript string to a JS string.

syntax

($/str s)

Converts a Racket string to a JS string, or vice versa, using js-string->string or js-string.

2.3 Reader Extensions🔗ℹ

#lang racketscript/base includes reader extensions that make it easier to interoperate with JavaScript. Specifically, RacketScript’s reader recognizes three delimiters:

  • #js

    Used to access JavaScript object properties via dot notation.

    Example:

    #js.req.body

    where req is a RacketScript variable.

    Equivalent to a series of #%js-ffi 'ref calls.

  • #js*

    Used to access JavaScript object properties via dot notation. The difference with "#js" is that "#js*" wraps the first identifier in a #%js-ffi 'var form, i.e., it is used to access properties of JavaScript variables rather than RacketScript variables.

    Example:

    #js*.JSON.parse

    where JSON is a JavaScript variable.

    Equivalent to a series of #%js-ffi 'ref calls where the first id is wrapped in a #%js-ffi 'var.

  • #js"some js string"

    Used to create JS strings.

    Note: JS strings are not compatible with Racket/RacketScript strings. Use $/str and other related API functions to convert between the two when needed.

    Example:

    (#js*.console.warn #js"Error!")

    Equivalent to a #%js-ffi call with 'string.