Symbols

Duktape supports ES2015 Symbols and also provides a Duktape specific hidden Symbol variant similar to internal strings in Duktape 1.x. Hidden Symbols differ from ES2015 Symbols in that they're hidden from ordinary Ecmascript code: they can't be created from Ecmascript code, won't be enumerated or JSON-serialized, and won't be returned even from Object.getOwnPropertyNames(). Properties with hidden Symbol keys can only be accessed by a direct property read/write when holding a reference to a hidden Symbol.

Duktape uses hidden Symbols for various implementation specific purposes, such as storing an object's finalizer reference. User code can also use hidden Symbols for its own purposes, e.g. to store hidden state in objects. User code should never try to access Duktape's hidden Symbol keyed properties: the set of such properties can change arbitrarily between versions.

Symbols of all kinds are represented internally using byte sequences which are invalid UTF-8; see symbols.rst for the current formats in use. When C code pushes a string using e.g. duk_push_string() and the byte sequence matches an internal Symbol format, the string value is automatically interpreted as a Symbol.

Note that the internal UTF-8 byte sequences cannot be created from Ecmascript code as a valid Ecmascript string. For example, a hidden Symbol might be represented using \xFFxyz, i.e. the byte sequence ff 78 79 7a, while the Ecmascript string "\u00ffxyz" would be represented as the CESU-8 bytes c3 bf 78 79 7a in memory.

Creating a Symbol is straightforward from C code:

/* Create a hidden Symbol which can then be used to read/write properties.
 * The Symbol can be passed on to Ecmascript code like any other string or
 * Symbol.  Terminating a string literal after a hex escape is safest to
 * avoid some ambiguous cases like "\xffab".
 */
duk_push_string(ctx, "\xff" "mySymbol");

For more discussion on C string hex escaping, see c_hex_esc.c.

Hidden Symbols cannot be created from Ecmascript code using the default built-ins alone. Standard ES2015 Symbols can be created using the Symbol built-in, e.g. as Symbol.for('foo'). When sandboxing, ensure that application C bindings don't accidentally provide a mechanism to create hidden Symbols by e.g. converting an input buffer as-is to a string without applying an encoding.

There's currently no special access control for properties with hidden Symbol keys: if user code has access to the Symbol, it can read/write the property value. This will most likely change in future major versions so that Ecmascript code cannot access a property with a hidden Symbol key, even when holding a reference to the hidden Symbol value.