Docly Developers
DocsUpdated 26 Oct 2026

Differences from standard JavaScript

HashJS is Docly's own JavaScript engine, written in .NET — not V8 and not Node.js. Most everyday JavaScript works as expected. This page lists what is missing and what behaves differently, in both .hash templates and #/API files unless noted.

Not available

Missing

Use instead

Map, WeakMap

An object literal, or Set for a list of unique values.

Symbol, Proxy

—

Object.freeze, Object.fromEntries, Object.create, Object.groupBy

Build the object in a loop. For grouping, the Docly method array.groupBy().

Array: fill, findLast, findLastIndex, reduceRight, toSorted, toReversed, Array.of

slice() followed by sort() or reverse(); a for loop.

String: search, matchAll, codePointAt

match() with the g flag, indexOf(), charCodeAt().

Number: toPrecision, toExponential, Number.isFinite, isFinite

toFixed(), Number.isNaN().

Date: toString, toLocaleString, getTimezoneOffset, and the setters (setDate, setHours, …)

format(date, pattern), toISOString(), and addDays(), addMonths() etc. to change a date.

setTimeout, setInterval, require(), npm packages

—

Rest parameters (function f(...args))

The arguments object, or pass an array. Spread when calling, f(...values), does work.

Computed property names ({ [key]: value }) and method shorthand ({ f() })

obj[key] = value, and f: function () .

Default import (import x from "…")

import from "…" or import * as m from "…".

Behaves differently

Area

In HashJS

Inline #…# expressions

Cannot contain a semicolon. Use a #{ … }# block for anything with ;.

write() and #…#

null and undefined print as an empty string, and an array prints as JSON (["a","b"], not a,b).

Reading a property of null or undefined

Throws a TypeError in .js files (as in standard JavaScript), but gives an empty value in .hash templates.

new Error("x")

Throws immediately, even without throw in front. Call Error("x") without new to create an error object without throwing.

JSON.stringify

A function inside the value (also a toJSON method on your own object) throws an error instead of being left out. With a replacer, for example JSON.stringify(obj, (key, value) => value), functions are left out as in standard JavaScript, but toJSON is still not called. The replacer and indent arguments otherwise work as in standard JavaScript.

Function expressions

A named function expression (var g = function h() { … }) cannot refer to itself as h inside its body; use g. Array destructuring in the parameters of a function expression or arrow function (([a, b]) => …) is not supported; destructure in the body instead.

switch

Each case must be a single literal value; values are compared without type conversion; default matches as soon as it is reached, so place it last.

array.indexOf / lastIndexOf

Items are compared by their JSON representation, so an object with the same content matches.

array.includes

Compares with .NET equality: no type conversion, objects match only the same instance.

array.reduce

An empty array without initial value returns null instead of throwing.

array.length = n

Does not shorten the array.

text.match("text")

A text argument is searched for literally, not as a regular expression.

text.replace / replaceAll with a text pattern

The replacement is inserted as is: $& and $1 are not interpreted.

text.replaceAll(regex)

A regular expression without the g flag replaces only the first match (standard JavaScript throws).

Object.keys / Object.entries on null

Return null instead of throwing.

Math.min / Math.max

Also accept an array. Text that is not a number is ignored.

Math.abs, floor, ceil, round

Text that is not a number counts as 0, and numeric text may use a comma as decimal separator.

-2 ** 2

Gives 4 (standard JavaScript rejects it as a syntax error).

Number(undefined)

Gives 0 (standard JavaScript gives NaN).

(n).toFixed(digits)

digits outside the valid range is clamped instead of throwing a RangeError.

[] +

Gives 0.

Object.prototype.toString.call(x)

Returns the value as text, not "[object Type]".

Docly additions

These are not part of standard JavaScript:

Addition

Description

The docly object

Docly's function library: data, files, HTTP, mail and more. All global helper functions are also available as docly.<name>.

#…# template syntax

Expressions, code blocks and control blocks in .hash pages. See HASH files.

array.groupBy(key)

Groups items by a property name or a function.

Math.min(array), Math.max(array)

Accept an array as well as separate numbers.

text.trim(chars)

Removes the given characters from both ends.

format(value, pattern), setCulture(culture)

Formats numbers and dates; the only place a culture is used. Everything else converts numbers with a dot as decimal separator.

Legacy template helpers

add(), cint(), where() and other global helpers from Docly's older template language. See Legacy template helpers.