ECMAScript Built-ins
Native JavaScript built-in objects and methods available in SSJS — which Array, String, Math, Number, Date, RegExp, and JSON members work, which are partial, and which are missing.
SSJS runs on the JINT engine with ES3/ES5 compatibility. Most native ECMAScript built-ins work as expected, but some methods are missing or behave incorrectly. This section documents what is safe to use, and links each member to its full details and any Polyfills.
Missing methods are listed here and on each section page. For drop-in implementations, see Polyfills.
Status legend
| Icon | Meaning |
|---|---|
| ✅ Works | Available and behaves as expected |
| ⚠️ Partial | Available but with a documented caveat or bug (see Notes) |
| ❌ Missing | Not available (or undefined) — use the workaround in Notes |
Quick Reference
The ES column shows the ECMAScript edition that standardized each member (ES3, ES5, or ES6). Method names link to their full details on the relevant section page.
Array Methods
| Method | ES | Status | Notes |
|---|---|---|---|
Array.prototype.concat(...) |
ES3 | ✅ Works | |
Array.prototype.join(sep) |
ES3 | ✅ Works | |
Array.prototype.length |
ES3 | ✅ Works | |
Array.prototype.pop() |
ES3 | ✅ Works | |
Array.prototype.push(item) |
ES3 | ✅ Works | |
Array.prototype.reverse() |
ES3 | ✅ Works | |
Array.prototype.shift() |
ES3 | ✅ Works | |
Array.prototype.toLocaleString() |
ES3 | ✅ Works | |
Array.prototype.unshift(item) |
ES3 | ✅ Works | |
Array.prototype.slice(start, end) |
ES3 | ⚠️ Partial | Positive/negative indices work; no-arg slice() throws — see Polyfills |
Array.prototype.sort(fn) |
ES3 | ⚠️ Partial | Works with a compare function; no-arg sort() throws — see Polyfills |
Array.prototype.splice(start, deleteCount, ...items) |
ES3 | ⚠️ Partial | Only splice(start, deleteCount) works; splice(start) throws and insert form is broken — see Polyfills |
Array.prototype.lastIndexOf(item) |
ES5 | ⚠️ Partial | Always returns -1; see Polyfills |
Array.prototype.indexOf(item) |
ES5 | ❌ Missing | See Polyfills |
Array.prototype.forEach(fn) |
ES5 | ❌ Missing | Use for loop or Polyfills |
Array.prototype.map(fn) |
ES5 | ❌ Missing | Use for loop or Polyfills |
Array.prototype.filter(fn) |
ES5 | ❌ Missing | Use for loop or Polyfills |
Array.prototype.reduce(fn) |
ES5 | ❌ Missing | Use for loop or Polyfills |
Array.prototype.reduceRight(fn) |
ES5 | ❌ Missing | Use for loop or Polyfills |
Array.prototype.some(fn) |
ES5 | ❌ Missing | Use for loop or Polyfills |
Array.prototype.every(fn) |
ES5 | ❌ Missing | Use for loop or Polyfills |
Array.prototype.find(fn) |
ES6 | ❌ Missing | Use for loop or Polyfills |
Array.prototype.findIndex(fn) |
ES6 | ❌ Missing | Use for loop or Polyfills |
Array.prototype.includes(item) |
ES6 | ❌ Missing | Use indexOf(x) !== -1 or Polyfills |
Array.prototype.fill(value) |
ES6 | ❌ Missing | See Polyfills |
Array.prototype.copyWithin(...) |
ES6 | ❌ Missing | See Polyfills |
Array.prototype.entries() |
ES6 | ❌ Missing | See Polyfills |
Array.prototype.keys() |
ES6 | ❌ Missing | Use a standard index for loop |
Array.prototype.values() |
ES6 | ❌ Missing | Use a standard index for loop |
Array.prototype.at(i) |
ES6 | ❌ Missing | Use arr[i] (and arr[arr.length + i] for negative i) |
Array.prototype.flat(depth) |
ES6 | ❌ Missing | Concatenate nested arrays manually in a loop |
Array.prototype.flatMap(fn) |
ES6 | ❌ Missing | Build the result with a for loop and push |
Array.prototype.findLast(fn) |
ES6 | ❌ Missing | Iterate from the end with a for loop |
Array.isArray(val) |
ES5 | ❌ Missing | See Polyfills |
Array.of(...) |
ES6 | ❌ Missing | See Polyfills |
Array.from(source) |
ES6 | ❌ Missing | Build the array with a for loop over the source |
String Methods
| Method | ES | Status | Notes |
|---|---|---|---|
String(value) |
ES3 | ✅ Works | Constructor as conversion function; also converts CLR/.NET objects (e.g. resp.content) to JS strings |
String.prototype.charAt(i) |
ES3 | ⚠️ Partial | Out-of-range index returns the last char, not "" |
String.prototype.charCodeAt(i) |
ES3 | ✅ Works | |
String.prototype.concat(...) |
ES3 | ✅ Works | |
String.prototype.indexOf(sub) |
ES3 | ✅ Works | |
String.prototype.lastIndexOf(sub) |
ES3 | ✅ Works | |
String.prototype.length |
ES3 | ✅ Works | |
String.prototype.localeCompare(other) |
ES3 | ✅ Works | |
String.prototype.match(regex) |
ES3 | ⚠️ Partial | No-match returns [] (empty array), not null; matches have no .index |
String.prototype.replace(search, rep) |
ES3 | ✅ Works | Regex supported |
String.prototype.slice(start, end) |
ES3 | ✅ Works | |
String.prototype.substring(start, end) |
ES3 | ✅ Works | |
String.prototype.search(regex) |
ES3 | ⚠️ Partial | Unreliable — no-match returns 0 instead of -1, and some real matches return the wrong index — see Polyfills |
String.prototype.split(sep) |
ES3 | ⚠️ Partial | Empty-separator split("") does not split into characters — see Polyfills |
String.prototype.substr(start, len) |
ES3 | ❌ Missing | Throws at runtime; use substring or the polyfill |
String.prototype.toLowerCase() |
ES3 | ✅ Works | |
String.prototype.toLocaleLowerCase() |
ES3 | ✅ Works | |
String.prototype.toUpperCase() |
ES3 | ✅ Works | |
String.fromCharCode(code) |
ES3 | ✅ Works | Static method |
String.prototype.trim() |
ES5 | ❌ Missing | See Polyfills |
String.prototype.startsWith(sub) |
ES6 | ❌ Missing | Use indexOf === 0 or polyfill |
String.prototype.endsWith(sub) |
ES6 | ❌ Missing | Use lastIndexOf or polyfill |
String.prototype.includes(sub) |
ES6 | ❌ Missing | Use indexOf !== -1 |
String.prototype.trimStart() |
ES6 | ❌ Missing | Use a /^\s+/ replace |
String.prototype.trimEnd() |
ES6 | ❌ Missing | Use a /\s+$/ replace |
String.prototype.padStart(len, ch) |
ES6 | ❌ Missing | Prepend pad characters in a loop |
String.prototype.padEnd(len, ch) |
ES6 | ❌ Missing | Append pad characters in a loop |
String.prototype.repeat(n) |
ES6 | ❌ Missing | Concatenate in a loop |
String.prototype.codePointAt(i) |
ES6 | ❌ Missing | Use charCodeAt for BMP characters |
Math Object
The ES3 Math members below work natively; Math.max / Math.min have argument-count caveats, the ES3 constant Math.LOG10E is missing, and all ES6 Math methods are unavailable.
| Method / Constant | ES | Status | Notes |
|---|---|---|---|
Math.abs(x) |
ES3 | ✅ Works | |
Math.ceil(x) |
ES3 | ✅ Works | |
Math.floor(x) |
ES3 | ✅ Works | |
Math.round(x) |
ES3 | ✅ Works | |
Math.pow(base, exp) |
ES3 | ✅ Works | |
Math.sqrt(x) |
ES3 | ✅ Works | |
Math.random() |
ES3 | ✅ Works | |
Math.log(x) |
ES3 | ✅ Works | |
Math.exp(x) |
ES3 | ✅ Works | |
Math.sin/cos/tan/asin/acos/atan/atan2 |
ES3 | ✅ Works | |
Math.PI / E / LN2 / LN10 / LOG2E / SQRT2 / SQRT1_2 |
ES3 | ✅ Works | |
Math.max(a, b, ...) |
ES3 | ⚠️ Partial | Throws with 3+ args; no-arg Math.max() returns 0 not -Infinity — compare two at a time or use the polyfill |
Math.min(a, b, ...) |
ES3 | ⚠️ Partial | Throws with 3+ args; no-arg Math.min() returns 0 not +Infinity — compare two at a time or use the polyfill |
Math.LOG10E |
ES3 | ❌ Missing | undefined in SFMC; use the literal 0.4342944819032518 |
Math.trunc(x) |
ES6 | ❌ Missing | x < 0 ? Math.ceil(x) : Math.floor(x) |
Math.sign(x) |
ES6 | ❌ Missing | x > 0 ? 1 : x < 0 ? -1 : 0 |
Math.cbrt(x) |
ES6 | ❌ Missing | Math.pow(x, 1 / 3) for non-negative x |
Math.log2(x) |
ES6 | ❌ Missing | Math.log(x) / Math.LN2 |
Math.log10(x) |
ES6 | ❌ Missing | Math.log(x) / Math.LN10 |
Math.hypot(a, b) |
ES6 | ❌ Missing | Math.sqrt(a * a + b * b) |
Math.expm1(x) |
ES6 | ❌ Missing | Math.exp(x) - 1 |
Math.log1p(x) |
ES6 | ❌ Missing | Math.log(1 + x) |
Math.sinh/cosh/tanh(x) |
ES6 | ❌ Missing | Build from Math.exp |
Math.asinh/acosh/atanh(x) |
ES6 | ❌ Missing | Build from Math.log/Math.sqrt |
Math.clz32(x) |
ES6 | ❌ Missing | Count leading zero bits manually — the emulation throws for a negative argument |
Math.fround(x) |
ES6 | ❌ Missing | No ES3-safe equivalent |
Math.imul(a, b) |
ES6 | ❌ Missing | Emulate with bitwise ops — non-negative operands only, and no 32-bit wrap |
Number
| Method / Constant | ES | Status | Notes |
|---|---|---|---|
Number.prototype.toFixed(digits) |
ES3 | ✅ Works | |
Number.prototype.toExponential([digits]) |
ES3 | ⚠️ Partial | No-arg form pads trailing zeros — always pass digits |
Number.prototype.toPrecision(digits) |
ES3 | ⚠️ Partial | digits counts decimal places, not significant digits (same result as toFixed(digits - 1)); the argument is mandatory and must be 1–21 |
Number.prototype.toString([radix]) |
ES3 | ⚠️ Partial | radix only supports 2, 8, 10, 16 — others throw “Invalid Base.” |
Number.prototype.valueOf() |
ES3 | ✅ Works | |
Number.MAX_VALUE / MIN_VALUE / NaN / NEGATIVE_INFINITY / POSITIVE_INFINITY |
ES3 | ⚠️ Partial | Defined but several wrong: MIN_VALUE negative, *_INFINITY signs swapped (MAX_VALUE/NaN correct) — use literals |
Number.isInteger(val) |
ES6 | ❌ Missing | Use typeof n === "number" && Math.floor(n) === n |
Number.isNaN(val) |
ES6 | ❌ Missing | Use global isNaN() |
Number.isFinite(val) |
ES6 | ❌ Missing | Use global isFinite() |
Number.parseInt(str) |
ES6 | ❌ Missing | Use global parseInt() |
Number.parseFloat(str) |
ES6 | ❌ Missing | Use global parseFloat() |
Number.isSafeInteger(val) |
ES6 | ❌ Missing | Compare against the literal 9007199254740991 |
Number.MAX_SAFE_INTEGER / MIN_SAFE_INTEGER / EPSILON |
ES6 | ❌ Missing | undefined — use literals (9007199254740991, -9007199254740991, 2.220446049250313e-16) |
Global Functions
Standard ECMAScript global functions (not SFMC-specific) — callable without any namespace.
| Function | ES | Status | Notes |
|---|---|---|---|
parseInt(str[, radix]) |
ES3 | ⚠️ Partial | Always pass a radix; returns NaN for trailing non-digits (parseInt("10px", 10) → NaN, not 10) |
parseFloat(str) |
ES3 | ⚠️ Partial | Returns NaN for trailing non-digits (parseFloat("1.5kg") → NaN); result uses 32-bit precision |
isNaN(val) |
ES3 | ✅ Works | |
isFinite(val) |
ES3 | ⚠️ Partial | Returns true for a non-numeric string (isFinite("abc"), isFinite(Number("abc")) → true); isFinite(NaN) is correct — use isNaN(Number(val)) |
eval(script) |
ES3 | ✅ Works | Evaluates a JS source string; direct eval sees local scope and Platform.Load Core globals. Executes arbitrary code — use sparingly (injection risk); prefer Platform.Function.ParseJSON for data. |
encodeURI(uri) |
ES3 | ⚠️ Partial | Space → + (not %20), lowercase hex |
encodeURIComponent(str) |
ES3 | ⚠️ Partial | Space → +, lowercase hex (%2f) |
decodeURI(uri) |
ES3 | ⚠️ Partial | Also decodes the reserved escapes the spec keeps, and turns + into a space — behaves like decodeURIComponent |
decodeURIComponent(str) |
ES3 | ⚠️ Partial | Decodes + as a space (form-urlencoded) |
escape(str) |
ES3 | ❌ Missing | undefined; use encodeURIComponent |
unescape(str) |
ES3 | ❌ Missing | undefined; use decodeURIComponent |
Global Values
Standard ECMAScript global value properties.
| Value | ES | Status | Notes |
|---|---|---|---|
undefined |
ES3 | ✅ Works | |
NaN |
ES3 | ⚠️ Partial | String(NaN) is lowercase nan |
Infinity |
ES3 | ⚠️ Partial | Sign inverted: Infinity > 0 is false, String(Infinity) is -infinity |
globalThis |
ES2020 | ❌ Missing | undefined — no global-object reference |
Boolean
| Member | ES | Status | Notes |
|---|---|---|---|
Boolean(value) |
ES3 | ⚠️ Partial | Returns a primitive, but Boolean(-1) and Boolean([]) are false; result has no methods |
new Boolean(value) |
ES3 | ⚠️ Partial | Capitalized True/False; boxed false is falsy; valueOf() does not unwrap |
Boolean.prototype |
ES3 | ✅ Works | toString.call(primitive) gives the correct lowercase form |
Missing ES6+ Objects
These top-level objects/types postdate the engine’s ES3/ES5 baseline and are entirely absent.
| Object | ES | Status | Notes |
|---|---|---|---|
Symbol |
ES6 | ❌ Missing | undefined; no iterator protocol — use string keys + index loops |
BigInt |
ES2020 | ❌ Missing | undefined; 10n literals are a syntax error — keep large integers as strings |
Map / Set / WeakMap / WeakSet |
ES6 | ❌ Missing | undefined; new throws Unknown type — use plain objects as dictionaries/sets |
Promise |
ES6 | ❌ Missing | undefined; engine is synchronous — Platform/HTTP calls block and return directly |
Iterator / Generator / async variants |
ES6+ | ❌ Missing | No iteration protocol; function* / async / await are unsupported |
Proxy / Reflect |
ES6 | ❌ Missing | undefined; no trap-based interception — use ES5 Object methods and operators |
ArrayBuffer / DataView / typed arrays |
ES6+ | ❌ Missing | undefined; no binary buffers — use plain arrays or Base64 strings |
WeakRef / FinalizationRegistry |
ES2021 | ❌ Missing | undefined; no weak refs or GC callbacks — hold normal references |
Intl |
ES2015 | ❌ Missing | undefined; toLocale* methods ignore locale — use AMPscript FormatNumber / FormatDate via TreatAsContent |
Object Methods
| Method | ES | Status | Notes |
|---|---|---|---|
Object.prototype.hasOwnProperty(v) |
ES3 | ✅ Works | Use inside for...in to skip inherited properties |
Object.prototype.toString() |
ES3 | ✅ Works | |
Object.prototype.valueOf() |
ES3 | ✅ Works | |
Object.prototype.isPrototypeOf(obj) |
ES3 | ❌ Broken | Present, but calling it hangs the engine — never call it; compare obj.constructor === Ctor |
Object.prototype.propertyIsEnumerable(v) |
ES3 | ⚠️ Partial | Broken — always returns false; use hasOwnProperty |
Object.defineProperty(obj, prop, desc) |
ES5 | ✅ Works | Static method |
Object.getPrototypeOf(obj) |
ES5 | ✅ Works | Static method |
Object.keys(obj) |
ES5 | ❌ Missing | Use for...in with hasOwnProperty |
Object.values(obj) |
ES6 | ❌ Missing | Use for...in with hasOwnProperty |
Object.entries(obj) |
ES6 | ❌ Missing | Use for...in with hasOwnProperty |
Object.assign(target, ...src) |
ES6 | ❌ Missing | Copy properties manually in a for...in loop |
Object.create(proto) |
ES5 | ❌ Missing | Use a constructor function with new |
Object.freeze(obj) |
ES5 | ❌ Missing | No equivalent — enforce immutability by convention |
Object.getOwnPropertyNames(obj) |
ES5 | ❌ Missing | Use for...in with hasOwnProperty |
Object.getOwnPropertyDescriptor(obj, prop) |
ES5 | ❌ Missing | Read the value directly + hasOwnProperty |
Object.defineProperties(obj, descs) |
ES5 | ❌ Missing | Call Object.defineProperty once per property |
Object.seal / isSealed / preventExtensions / isExtensible |
ES5 | ❌ Missing | No runtime extensibility control |
Function Methods
| Method / Property | ES | Status | Notes |
|---|---|---|---|
Function.prototype.call(thisArg, ...) |
ES3 | ✅ Works | |
Function.prototype.apply(thisArg, argsArray) |
ES3 | ✅ Works | |
arguments |
ES3 | ✅ Works | Array-like object inside every function |
Function(...args, body) |
ES3 | ✅ Works | Constructor works with or without new |
Function.prototype.toString() |
ES3 | ⚠️ Partial | Returns [object Function], not the source |
fn.constructor |
ES3 | ⚠️ Partial | fn.constructor === Function is false; use instanceof Function |
Function.prototype.bind(thisArg, ...) |
ES5 | ❌ Missing | Prototype is sealed — use the bindFn helper in Polyfills |
Function.prototype.length |
ES3 | ❌ Broken | Reading it throws; track arity yourself — see Known Bugs |
Function.prototype.name |
ES3 | ❌ Missing | undefined |
Function.prototype.caller |
ES3 | ❌ Missing | undefined (deprecated) |
Error
| Member | ES | Status | Notes |
|---|---|---|---|
new Error([message]) |
ES3 | ⚠️ Partial | Constructor works, but .message on a JS-constructed Error reads undefined — recover the message via String(e); engine-raised platform errors do carry .message / .description |
EvalError / RangeError / ReferenceError / SyntaxError / TypeError / URIError |
ES3 | ⚠️ Partial | All six legacy subtypes are present and constructible; they share the base Error quirks (.message undefined, instanceof always false) |
AggregateError / SuppressedError / InternalError |
ES2021+ | ❌ Missing | Newer / non-standard error types are absent — use the base Error constructor |
Date Methods
Value-confirmed Date members — see Date Methods for examples.
| Method | ES | Status | Notes |
|---|---|---|---|
Date.prototype.getFullYear() |
ES3 | ✅ Works | |
Date.prototype.getMonth() |
ES3 | ✅ Works | 0-based |
Date.prototype.getDate() |
ES3 | ✅ Works | |
Date.prototype.getDay() |
ES3 | ✅ Works | |
Date.prototype.getHours() |
ES3 | ✅ Works | |
Date.prototype.getMinutes() |
ES3 | ✅ Works | |
Date.prototype.getSeconds() |
ES3 | ✅ Works | |
Date.prototype.getMilliseconds() |
ES3 | ⚠️ Partial | Frequently off by one — do not rely on exact millisecond values |
Date.prototype.getTime() |
ES3 | ✅ Works | |
Date.prototype.getTimezoneOffset() |
ES3 | ✅ Works | |
Date.prototype.valueOf() |
ES3 | ✅ Works | |
Date.prototype.getUTCFullYear() … getUTCMilliseconds() |
ES3 | ✅ Works | Full getUTC* family confirmed |
Date.prototype.toString() |
ES3 | ✅ Works | |
Date.prototype.toDateString() |
ES3 | ✅ Works | |
Date.prototype.toTimeString() |
ES3 | ✅ Works | |
Date.prototype.toUTCString() |
ES3 | ✅ Works | |
Date.prototype.toISOString() |
ES5 | ❌ Missing | Build the ISO string manually |
Date.prototype.toJSON() |
ES5 | ❌ Missing | Absent (depends on toISOString) |
Date.now() |
ES5 | ⚠️ Partial | Static — returns a Date object, not a number |
Date.parse(str) |
ES3 | ⚠️ Partial | Static — invalid strings return 0, not NaN; date-only parses as local |
Date.UTC(year[, ...]) |
ES3 | ⚠️ Partial | Static — pass ≥ 2 args; year-only form returns a nonsense value, not NaN |
RegExp
Value-confirmed RegExp members — see Regular Expressions for syntax, flags, and examples.
| Method / Property | ES | Status | Notes |
|---|---|---|---|
RegExp.prototype.test(string) |
ES3 | ✅ Works | |
RegExp.prototype.exec(string) |
ES3 | ⚠️ Partial | Full match result[0], .index, .input work, but capture groups result[1]+ are undefined and result.length is always 3; lastIndex does not advance |
RegExp.prototype.source |
ES3 | ✅ Works | |
RegExp.prototype.global |
ES3 | ✅ Works | |
RegExp.prototype.lastIndex |
ES3 | ⚠️ Partial | Does not advance after exec()/test() with the g flag, and manual assignment is ignored — use String.match(/.../g) to get all matches |
RegExp.prototype.ignoreCase |
ES3 | ❌ Missing | undefined in SFMC; track the i flag yourself |
RegExp.prototype.multiline |
ES3 | ❌ Missing | undefined in SFMC; track the m flag yourself |
re instanceof RegExp |
ES3 | ⚠️ Partial | Always false (even for new RegExp(...)) — use re.constructor === RegExp |
JSON
The native JSON object is unavailable — see JSON for the SFMC alternatives.
| Method | ES | Status | Notes |
|---|---|---|---|
JSON.parse(text) |
ES5 | ❌ Missing | Use Platform.Function.ParseJSON |
JSON.stringify(value) |
ES5 | ❌ Missing | Use Platform.Function.Stringify or the bare-name Stringify Core global |
In This Section
| Page | Description |
|---|---|
| Global Functions | URI encode/decode functions (form-urlencoded quirks) and the missing escape/unescape |
| Global Values | undefined, NaN, the broken Infinity, and the missing globalThis |
| Boolean | The Boolean constructor — falsy negative numbers, falsy [], and the boxed-object True/False quirk |
| Symbol | Not available (ES6) — no unique primitives or iterator protocol |
| BigInt | Not available (ES2020) — no arbitrary-precision integers |
| Array Methods | Safe and polyfillable array methods |
| String Methods | The String() constructor/conversion function and safe / polyfillable string methods |
| Error() | The Error constructor and the SFMC-specific .message caveat |
| Error Types | The six present legacy Error subtypes and the missing AggregateError / SuppressedError / InternalError |
| Keyed Collections | Not available (ES6) — Map / Set / WeakMap / WeakSet are absent |
| Promises & Iteration | Not available (ES6+) — Promise, iterators, generators, and async/await are absent (synchronous engine) |
| Reflection | Not available (ES6) — Proxy and Reflect are absent |
| Typed Arrays | Not available (ES6+) — ArrayBuffer, DataView, Atomics, and all typed-array views are absent |
| Memory Management | Not available (ES2021) — WeakRef and FinalizationRegistry are absent |
| Internationalization | Not available (ES2015) — Intl is absent and toLocale* methods ignore locale |
| Math | Math object reference |
| Number Methods | Number methods, constants, and global numeric functions |
| Object Methods | hasOwnProperty, defineProperty, and missing Object statics |
| Function Methods | Native call / apply, the arguments object and Function() constructor, the bind (bindFn) helper, and the broken .length / .name / toString / constructor members |
| Date Methods | Value-confirmed Date getters, string conversions, and Date.UTC |
| Regular Expressions | RegExp test, exec, and the source / global / lastIndex accessors (ignoreCase / multiline are undefined in SFMC) |
| JSON | JSON.parse / JSON.stringify are unavailable — use Platform.Function.ParseJSON / Platform.Function.Stringify |