Each member below is tagged with its ECMAScript edition, using labels such as ES3, ES5, ES6, and year-based labels for later additions. Methods that need a polyfill link to Polyfills.

The new findLastIndex assertion scripts derive from runtime evidence dated 2026-09-06 and are statically checked, not executed live. See the shared native-absence evidence scope for contexts and limits.

Status legend

Icon Meaning
✅ Works Available and behaves as expected
⚠️ Partial Available but with a documented caveat or bug
❌ Missing Not available — use the workaround / polyfill

Members

Member ES Status Notes
push(...items) ES3 ✅ Works  
pop() ES3 ✅ Works  
shift() ES3 ✅ Works  
unshift(...items) ES3 ✅ Works  
concat(...arrays) ES3 ✅ Works  
join(separator) ES3 ✅ Works  
reverse() ES3 ✅ Works  
length ES3 ✅ Works  
toLocaleString() ES3 ✅ Works  
slice(start, end) ES3 ⚠️ Partial Positive/negative indices work; the no-arg slice() throws — see Polyfills
sort(compareFn) ES3 ⚠️ Partial Works with a compare function; the no-arg sort() throws — see Polyfills
splice(start, deleteCount, ...items) ES3 ⚠️ Partial Only splice(start, deleteCount) works; splice(start) throws and the insert form is broken — see Polyfills
indexOf(searchValue, fromIndex) ES5 ❌ Missing See Polyfills
lastIndexOf(searchValue, fromIndex) ES5 ⚠️ Partial Broken — always returns -1; see Polyfills
forEach(fn) ES5 ❌ Missing Use a for loop or the polyfill
map(fn) ES5 ❌ Missing Use a for loop or the polyfill
filter(fn) ES5 ❌ Missing Use a for loop or the polyfill
reduce(fn, initial) ES5 ❌ Missing Use a for loop or the polyfill
reduceRight(fn, initial) ES5 ❌ Missing Use a for loop or the polyfill
some(fn) ES5 ❌ Missing Use a for loop or the polyfill
every(fn) ES5 ❌ Missing Use a for loop or the polyfill
find(fn) ES6 ❌ Missing Use a for loop or the polyfill
findIndex(fn) ES6 ❌ Missing Use a for loop or the polyfill
includes(searchValue) ES6 ❌ Missing Use indexOf(x) !== -1 or the polyfill
fill(value, start, end) ES6 ❌ Missing See Polyfills
copyWithin(target, start, count) ES6 ❌ Missing See Polyfills
entries() ES6 ❌ Missing See Polyfills
keys() ES6 ❌ Missing Use a standard index for loop
values() ES6 ❌ Missing Use a standard index for loop
at(index) ES6 ❌ Missing Use arr[i] (and arr[arr.length + i] for negative i)
flat(depth) ES6 ❌ Missing Concatenate nested arrays manually in a loop
flatMap(fn) ES6 ❌ Missing Build the result with a for loop and push
findLast(fn) ES6 ❌ Missing Iterate from the end with a for loop
findLastIndex ES2023 ❌ Missing Not available natively
toReversed ES2023 ❌ Missing Not available natively
toSorted ES2023 ❌ Missing Not available natively
toSpliced ES2023 ❌ Missing Not available natively
Array.isArray(value) ES5 ❌ Missing See Polyfills
Array.of(...items) ES6 ❌ Missing See Polyfills
Array.from(source) ES6 ❌ Missing Build the array with a for loop over the source

push

(ES3) — ✅ Works. Appends one or more items to the end of the array and returns the new length.

var arr = [1, 2, 3];
arr.push(4);   // [1, 2, 3, 4]
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: push(...items)
 *
 * Proves:
 *   1. push is available (typeof "function").
 *   2. Appending a single item mutates the array in place: [1,2,3] -> [1,2,3,4].
 *   3. push returns the NEW length of the array.
 *   4. Multiple items can be appended in one call.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}

var pushArr = [1, 2, 3];
assert("typeof [].push is function", typeof pushArr.push, "function");
var pushRet = pushArr.push(4);
assert("[1,2,3].push(4) makes [1,2,3,4]", pushArr.join(","), "1,2,3,4");
assert("push returns the new length 4", pushRet, "4");
var pushArr2 = [1];
var pushRet2 = pushArr2.push(2, 3);
assert("push(2,3) appends both items", pushArr2.join(","), "1,2,3");
assert("push(2,3) returns the new length 3", pushRet2, "3");
</script>

pop

(ES3) — ✅ Works. Removes and returns the last item.

var arr = [1, 2, 3];
var last = arr.pop();   // 3, arr = [1, 2]
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: pop()
 *
 * Proves:
 *   1. pop is available (typeof "function").
 *   2. pop RETURNS the last item: [1,2,3].pop() === 3.
 *   3. pop MUTATES the array in place, leaving [1,2].
 *   4. pop on an empty array returns undefined.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}

var popArr = [1, 2, 3];
assert("typeof [].pop is function", typeof popArr.pop, "function");
var popLast = popArr.pop();
assert("[1,2,3].pop() returns 3", popLast, "3");
assert("after pop the array is [1,2]", popArr.join(","), "1,2");
assert("after pop the length is 2", popArr.length, "2");
var popEmpty = [];
assert("[].pop() is undefined", typeof popEmpty.pop(), "undefined");
</script>

shift

(ES3) — ✅ Works. Removes and returns the first item.

var arr = [1, 2, 3];
var first = arr.shift();   // 1, arr = [2, 3]
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: shift()
 *
 * Proves:
 *   1. shift is available (typeof "function").
 *   2. shift RETURNS the first item: [1,2,3].shift() === 1.
 *   3. shift MUTATES the array in place, leaving [2,3].
 *   4. shift on an empty array returns undefined.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}

var shiftArr = [1, 2, 3];
assert("typeof [].shift is function", typeof shiftArr.shift, "function");
var shiftFirst = shiftArr.shift();
assert("[1,2,3].shift() returns 1", shiftFirst, "1");
assert("after shift the array is [2,3]", shiftArr.join(","), "2,3");
assert("after shift the length is 2", shiftArr.length, "2");
var shiftEmpty = [];
assert("[].shift() is undefined", typeof shiftEmpty.shift(), "undefined");
</script>

unshift

(ES3) — ✅ Works. Prepends one or more items and returns the new length.

var arr = [1, 2, 3];
arr.unshift(0);   // arr = [0, 1, 2, 3]
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: unshift(...items)
 *
 * Proves:
 *   1. unshift is available (typeof "function").
 *   2. Prepending mutates the array in place: [1,2,3] -> [0,1,2,3].
 *   3. unshift returns the NEW length.
 *   4. Several items can be prepended in one call, keeping their order.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}

var unshiftArr = [1, 2, 3];
assert("typeof [].unshift is function", typeof unshiftArr.unshift, "function");
var unshiftRet = unshiftArr.unshift(0);
assert("[1,2,3].unshift(0) makes [0,1,2,3]", unshiftArr.join(","), "0,1,2,3");
assert("unshift returns the new length 4", unshiftRet, "4");
var unshiftArr2 = [3];
var unshiftRet2 = unshiftArr2.unshift(1, 2);
assert("unshift(1,2) prepends in order", unshiftArr2.join(","), "1,2,3");
assert("unshift(1,2) returns the new length 3", unshiftRet2, "3");
</script>

concat

(ES3) — ✅ Works. Returns a new array combining the array with the given arrays/values.

var combined = [1, 2].concat([3, 4]);   // [1, 2, 3, 4]
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: concat(...arrays)
 *
 * Proves:
 *   1. concat is available (typeof "function").
 *   2. [1,2].concat([3,4]) returns a new [1,2,3,4].
 *   3. concat does NOT mutate the receiver.
 *   4. Plain values and several arrays can be concatenated in one call.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}

var concatBase = [1, 2];
assert("typeof [].concat is function", typeof concatBase.concat, "function");
var concatOut = concatBase.concat([3, 4]);
assert("[1,2].concat([3,4]) is [1,2,3,4]", concatOut.join(","), "1,2,3,4");
assert("concat leaves the receiver unchanged", concatBase.join(","), "1,2");
assert("concat returns a new array (not the receiver)", concatOut === concatBase, "false");
assert("concat accepts plain values", [1].concat(2, 3).join(","), "1,2,3");
assert("concat accepts several arrays", [1].concat([2], [3, 4]).join(","), "1,2,3,4");
</script>

join

(ES3) — ✅ Works. Joins all elements into a string using the given separator.

["Hello", "World"].join(", ");   // "Hello, World"
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: join(separator)
 *
 * Proves:
 *   1. join is available (typeof "function").
 *   2. ["Hello","World"].join(", ") returns "Hello, World".
 *   3. join returns a string.
 *   4. The no-argument form uses the default "," separator.
 *   5. An empty array joins to the empty string.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}

var joinArr = ["Hello", "World"];
assert("typeof [].join is function", typeof joinArr.join, "function");
assert("['Hello','World'].join(', ') is 'Hello, World'", joinArr.join(", "), "Hello, World");
assert("join returns a string", typeof joinArr.join(", "), "string");
assert("join() defaults to a comma separator", [1, 2, 3].join(), "1,2,3");
assert("join('') concatenates without a separator", [1, 2, 3].join(""), "123");
assert("[].join(',') is the empty string", [].join(","), "");
</script>

reverse

(ES3) — ✅ Works. Reverses the array in place.

var arr = [1, 2, 3];
arr.reverse();   // [3, 2, 1]
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: reverse()
 *
 * Proves:
 *   1. reverse is available (typeof "function").
 *   2. [1,2,3].reverse() reverses IN PLACE, giving [3,2,1].
 *   3. reverse returns the same array object it mutated.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}

var revArr = [1, 2, 3];
assert("typeof [].reverse is function", typeof revArr.reverse, "function");
var revRet = revArr.reverse();
assert("[1,2,3].reverse() gives [3,2,1]", revArr.join(","), "3,2,1");
assert("reverse mutates in place (same object returned)", revRet === revArr, "true");
assert("reverse of a 2-item array", ["a", "b"].reverse().join(","), "b,a");
</script>

length

(ES3) — ✅ Works. The number of elements in the array.

[1, 2, 3].length;   // 3
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: length
 *
 * Proves:
 *   1. [1,2,3].length is 3 and is a number.
 *   2. An empty array has length 0.
 *   3. length tracks mutations made through push and pop.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}

var lenArr = [1, 2, 3];
assert("[1,2,3].length is 3", lenArr.length, "3");
assert("typeof length is number", typeof lenArr.length, "number");
assert("[].length is 0", [].length, "0");
lenArr.push(4);
assert("length is 4 after push", lenArr.length, "4");
lenArr.pop();
assert("length is 3 again after pop", lenArr.length, "3");
</script>

toLocaleString

(ES3) — ✅ Works. Returns a locale-specific string representation.

[1, 2, 3].toLocaleString();   // "1,2,3"
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: toLocaleString()
 *
 * Proves:
 *   1. toLocaleString is available (typeof "function").
 *   2. [1,2,3].toLocaleString() returns "1,2,3".
 *   3. The result is a string.
 *   4. An empty array yields the empty string.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}

var tlsArr = [1, 2, 3];
assert("typeof [].toLocaleString is function", typeof tlsArr.toLocaleString, "function");
assert("[1,2,3].toLocaleString() is '1,2,3'", tlsArr.toLocaleString(), "1,2,3");
assert("toLocaleString returns a string", typeof tlsArr.toLocaleString(), "string");
assert("[].toLocaleString() is the empty string", [].toLocaleString(), "");
</script>

slice

(ES3) — ⚠️ Partial. Returns a shallow copy of a portion of the array. Positive and negative indices work correctly (slice(-2), slice(1, -1) return the expected ranges). The one bug is the no-argument form slice(), which throws Index was outside the bounds of the array. — always pass at least a start index (slice(0)) to copy the whole array, or apply the polyfill.

var arr = [0, 1, 2, 3, 4];
arr.slice(1, 3);   // [1, 2]
arr.slice(-2);     // [3, 4]   — negative indices work
arr.slice(1, -1);  // [1, 2, 3]
arr.slice(0);      // copy of arr — use this instead of arr.slice()
// arr.slice() — no-arg form THROWS; use arr.slice(0) or the polyfill
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: slice(start, end) - PARTIAL
 *
 * Proves:
 *   1. slice is available (typeof "function").
 *   2. slice(1, 3) returns [1, 2] from [0,1,2,3,4].
 *   3. NEGATIVE indices work correctly: slice(-2) -> [3,4], slice(1,-1) -> [1,2,3].
 *   4. slice(0) copies the whole array and does not mutate the receiver.
 *   5. DEVIATION: the no-argument form slice() THROWS
 *      "Index was outside the bounds of the array."
 *      (spec: slice() returns a shallow copy of the whole array).
 *   6. The documented workaround slice(0) produces exactly that copy.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var sliceArr = [0, 1, 2, 3, 4];
assert("typeof [].slice is function", typeof sliceArr.slice, "function");
assert("slice(1,3) is [1,2]", sliceArr.slice(1, 3).join(","), "1,2");
assert("slice(-2) is [3,4] - negative start works", sliceArr.slice(-2).join(","), "3,4");
assert("slice(1,-1) is [1,2,3] - negative end works", sliceArr.slice(1, -1).join(","), "1,2,3");
assert("slice(0) copies the whole array", sliceArr.slice(0).join(","), "0,1,2,3,4");
assert("slice(0) returns a NEW array", sliceArr.slice(0) === sliceArr, "false");
assert("slice does not mutate the receiver", sliceArr.join(","), "0,1,2,3,4");
assertThrows("DEV slice() no-arg form throws (spec: full copy)", function () { var a = [0, 1, 2]; return a.slice(); });
assert("workaround slice(0) equals the original content", [7, 8, 9].slice(0).join(","), "7,8,9");
</script>

sort

(ES3) — ⚠️ Partial. Sorts in place. A supplied compare function works correctly (numeric and string comparators both sort as expected). The one bug is the no-argument form sort(), which throws Failed to compare two elements in the array. — always pass an explicit compare function, or apply the polyfill if you need the default lexicographic order.

var arr = [3, 1, 4, 1, 5];
arr.sort(function (a, b) { return a - b; });   // ascending — works
// arr.sort() — no-arg form THROWS; pass a compare function or use the polyfill
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: sort(compareFn) - PARTIAL
 *
 * Proves:
 *   1. sort is available (typeof "function").
 *   2. A numeric compare function sorts ascending, in place.
 *   3. A string compare function sorts as expected.
 *   4. sort returns the same array object it mutated.
 *   5. DEVIATION: the no-argument form sort() THROWS
 *      "Failed to compare two elements in the array."
 *      (spec: sort() sorts lexicographically by default).
 *   6. The documented workaround - always pass a compare function - works.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var sortArr = [3, 1, 4, 1, 5];
assert("typeof [].sort is function", typeof sortArr.sort, "function");
var sortRet = sortArr.sort(function (a, b) { return a - b; });
assert("numeric comparator sorts ascending", sortArr.join(","), "1,1,3,4,5");
assert("sort returns the same array object", sortRet === sortArr, "true");
var sortDesc = [3, 1, 4].sort(function (a, b) { return b - a; });
assert("numeric comparator sorts descending", sortDesc.join(","), "4,3,1");
var sortStr = ["pear", "apple", "fig"].sort(function (a, b) { if (a < b) { return -1; } if (a > b) { return 1; } return 0; });
assert("string comparator sorts alphabetically", sortStr.join(","), "apple,fig,pear");
assertThrows("DEV sort() no-arg form throws (spec: lexicographic sort)", function () { var a = [3, 1, 2]; return a.sort(); });
assert("workaround: always pass a comparator", [10, 9].sort(function (a, b) { return a - b; }).join(","), "9,10");
</script>

splice

(ES3) — ⚠️ Partial. Signature: splice(start[, deleteCount[, item1[, ...itemN]]]).

Show test script — proves splice(start) throws, the two-arg delete works with clamping, and the insert form overwrites from the left
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: splice(start, deleteCount, ...items) - PARTIAL
 *
 * Proves:
 *   1. splice is available (typeof "function").
 *   2. The two-argument DELETE form works: ["a","b","c","d"].splice(1,1)
 *      leaves ["a","c","d"].
 *   3. An over-large deleteCount is clamped to the remaining length.
 *   4. DEVIATION: the one-argument form splice(start) THROWS
 *      "Index was outside the bounds of the array."
 *      (spec: removes everything from start to the end).
 *   5. DEVIATION: the INSERT form is broken - as soon as a third argument is
 *      passed the engine ignores start/deleteCount and overwrites from the left:
 *        ["a","b","c","d"].splice(1,1,"X")      -> ["X","b","c","d"]
 *          (spec: ["a","X","c","d"])
 *        ["a","b","c","d"].splice(1,0,"B","C")  -> ["B","C","c","d"]
 *          (spec: ["a","B","C","b","c","d"])
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var spArr = ["a", "b", "c", "d"];
assert("typeof [].splice is function", typeof spArr.splice, "function");
spArr.splice(1, 1);
assert("splice(1,1) deletes one item -> a,c,d", spArr.join(","), "a,c,d");
var spClamp = ["a", "b", "c", "d"];
spClamp.splice(1, 10);
assert("over-large deleteCount is clamped -> a", spClamp.join(","), "a");
assertThrows("DEV splice(start) one-arg form throws (spec: delete to end)", function () { var a = ["a", "b", "c", "d"]; return a.splice(2); });
var spIns = ["a", "b", "c", "d"];
spIns.splice(1, 1, "X");
assert("DEV splice(1,1,'X') overwrites from the left -> X,b,c,d (spec: a,X,c,d)", spIns.join(","), "X,b,c,d");
var spIns2 = ["a", "b", "c", "d"];
spIns2.splice(1, 0, "B", "C");
assert("DEV splice(1,0,'B','C') overwrites from the left -> B,C,c,d (spec: a,B,C,b,c,d)", spIns2.join(","), "B,C,c,d");
</script>

// Two-argument delete form works natively:
var arr = ["a", "b", "c", "d"];
arr.splice(1, 1);    // ["a", "c", "d"]
arr.splice(1, 10);   // deleteCount is clamped to the remaining length

// One-argument delete form REQUIRES the polyfill:
// arr.splice(2) — THROWS "Index was outside the bounds of the array."

// Insert form REQUIRES the polyfill (native engine overwrites from the left):
var arr2 = ["a", "b", "c", "d"];
arr2.splice(1, 1, "X");        // native gives ["X", "b", "c", "d"] (wrong)
arr2.splice(1, 0, "B", "C");   // native gives ["B", "C", "c", "d"] (wrong)

indexOf

(ES5) — ❌ Missing. Not available in SFMC. Apply the polyfill, or scan with a for loop.

function indexOf(arr, value) {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] === value) { return i; }
    }
    return -1;
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: indexOf(searchValue, fromIndex) - MISSING
 *
 * Proves:
 *   1. Array.prototype.indexOf is NOT available in SFMC
 *      (typeof [].indexOf is "undefined"; spec (ES5): a function).
 *   2. Calling it throws instead of returning an index.
 *   3. The documented for-loop workaround returns the index of a match
 *      and -1 when the value is absent.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var ioArr = ["a", "b", "c"];
assert("DEV typeof [].indexOf is undefined (spec ES5: function)", typeof ioArr.indexOf, "undefined");
assertThrows("DEV [].indexOf('b') throws (spec: returns 1)", function () { var a = ["a", "b"]; return a.indexOf("b"); });

function indexOfPoly(arr, value) {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] === value) { return i; }
    }
    return -1;
}
assert("workaround indexOf finds 'b' at 1", indexOfPoly(ioArr, "b"), "1");
assert("workaround indexOf finds 'a' at 0", indexOfPoly(ioArr, "a"), "0");
assert("workaround indexOf returns -1 when absent", indexOfPoly(ioArr, "z"), "-1");
</script>

lastIndexOf

(ES5) — ⚠️ Partial. Present but broken — always returns -1. Apply the polyfill, or scan from the end with a for loop.

function lastIndexOf(arr, value) {
    for (var i = arr.length - 1; i >= 0; i--) {
        if (arr[i] === value) { return i; }
    }
    return -1;
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: lastIndexOf(searchValue, fromIndex) - PARTIAL (broken)
 *
 * Proves:
 *   1. lastIndexOf IS present (typeof "function") - unlike indexOf.
 *   2. DEVIATION: it is broken and ALWAYS returns -1, even for a value that
 *      is clearly in the array (spec: the last matching index).
 *   3. The documented reverse for-loop workaround returns the correct last
 *      index and -1 when the value is absent.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}

var liArr = ["a", "b", "a", "c"];
assert("typeof [].lastIndexOf is function", typeof liArr.lastIndexOf, "function");
assert("DEV lastIndexOf('a') returns -1 (spec: 2)", liArr.lastIndexOf("a"), "-1");
assert("DEV lastIndexOf('c') returns -1 (spec: 3)", liArr.lastIndexOf("c"), "-1");
assert("lastIndexOf('z') returns -1 (absent value)", liArr.lastIndexOf("z"), "-1");

function lastIndexOfPoly(arr, value) {
    for (var i = arr.length - 1; i >= 0; i--) {
        if (arr[i] === value) { return i; }
    }
    return -1;
}
assert("workaround lastIndexOf('a') is 2", lastIndexOfPoly(liArr, "a"), "2");
assert("workaround lastIndexOf('c') is 3", lastIndexOfPoly(liArr, "c"), "3");
assert("workaround lastIndexOf('z') is -1", lastIndexOfPoly(liArr, "z"), "-1");
</script>

forEach

(ES5) — ❌ Missing. Use a for loop or the polyfill.

for (var i = 0; i < arr.length; i++) {
    var item = arr[i];
    // process item
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: forEach(fn) - MISSING
 *
 * Proves:
 *   1. Array.prototype.forEach is NOT available
 *      (typeof [].forEach is "undefined"; spec (ES5): a function).
 *   2. Calling it throws.
 *   3. The documented index for-loop visits every element in order.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var feArr = [1, 2, 3];
assert("DEV typeof [].forEach is undefined (spec ES5: function)", typeof feArr.forEach, "undefined");
assertThrows("DEV [].forEach(fn) throws (spec: visits each item)", function () { var a = [1]; return a.forEach(function () { return 1; }); });

var seen = [];
for (var i = 0; i < feArr.length; i++) {
    seen.push(feArr[i]);
}
assert("workaround for-loop visits every item in order", seen.join(","), "1,2,3");
assert("workaround visited exactly length items", seen.length, "3");
</script>

map

(ES5) — ❌ Missing. Use a for loop or the polyfill.

var doubled = [];
for (var i = 0; i < arr.length; i++) {
    doubled.push(arr[i] * 2);
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: map(fn) - MISSING
 *
 * Proves:
 *   1. Array.prototype.map is NOT available
 *      (typeof [].map is "undefined"; spec (ES5): a function).
 *   2. Calling it throws.
 *   3. The documented for-loop + push workaround produces the mapped array
 *      and leaves the source untouched.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var mapArr = [1, 2, 3];
assert("DEV typeof [].map is undefined (spec ES5: function)", typeof mapArr.map, "undefined");
assertThrows("DEV [].map(fn) throws (spec: returns a mapped array)", function () { var a = [1]; return a.map(function (x) { return x; }); });

var doubled = [];
for (var i = 0; i < mapArr.length; i++) {
    doubled.push(mapArr[i] * 2);
}
assert("workaround for-loop map gives 2,4,6", doubled.join(","), "2,4,6");
assert("workaround leaves the source array unchanged", mapArr.join(","), "1,2,3");
</script>

filter

(ES5) — ❌ Missing. Use a for loop or the polyfill.

var evens = [];
for (var i = 0; i < arr.length; i++) {
    if (arr[i] % 2 === 0) { evens.push(arr[i]); }
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: filter(fn) - MISSING
 *
 * Proves:
 *   1. Array.prototype.filter is NOT available
 *      (typeof [].filter is "undefined"; spec (ES5): a function).
 *   2. Calling it throws.
 *   3. The documented for-loop workaround collects only matching items,
 *      and yields an empty array when nothing matches.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var filArr = [1, 2, 3, 4];
assert("DEV typeof [].filter is undefined (spec ES5: function)", typeof filArr.filter, "undefined");
assertThrows("DEV [].filter(fn) throws (spec: returns matching items)", function () { var a = [1]; return a.filter(function (x) { return true; }); });

var evens = [];
for (var i = 0; i < filArr.length; i++) {
    if (filArr[i] % 2 === 0) { evens.push(filArr[i]); }
}
assert("workaround for-loop filter gives 2,4", evens.join(","), "2,4");

var none = [];
for (var j = 0; j < filArr.length; j++) {
    if (filArr[j] > 99) { none.push(filArr[j]); }
}
assert("workaround yields an empty array when nothing matches", none.length, "0");
</script>

reduce

(ES5) — ❌ Missing. Use a for loop or the polyfill.

var sum = 0;
for (var i = 0; i < arr.length; i++) {
    sum += arr[i];
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: reduce(fn, initial) - MISSING
 *
 * Proves:
 *   1. Array.prototype.reduce is NOT available
 *      (typeof [].reduce is "undefined"; spec (ES5): a function).
 *   2. Calling it throws.
 *   3. The documented accumulator for-loop sums the array, and an empty
 *      array leaves the initial value untouched.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var redArr = [1, 2, 3, 4];
assert("DEV typeof [].reduce is undefined (spec ES5: function)", typeof redArr.reduce, "undefined");
assertThrows("DEV [].reduce(fn,0) throws (spec: folds to a single value)", function () { var a = [1]; return a.reduce(function (acc, x) { return acc + x; }, 0); });

var sum = 0;
for (var i = 0; i < redArr.length; i++) {
    sum += redArr[i];
}
assert("workaround accumulator loop sums to 10", sum, "10");

var emptySum = 7;
var emptyArr = [];
for (var j = 0; j < emptyArr.length; j++) {
    emptySum += emptyArr[j];
}
assert("workaround keeps the initial value for an empty array", emptySum, "7");
</script>

reduceRight

(ES5) — ❌ Missing. Use a reverse for loop or the polyfill.

var sum = 0;
for (var i = arr.length - 1; i >= 0; i--) {
    sum += arr[i];
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: reduceRight(fn, initial) - MISSING
 *
 * Proves:
 *   1. Array.prototype.reduceRight is NOT available
 *      (typeof [].reduceRight is "undefined"; spec (ES5): a function).
 *   2. Calling it throws.
 *   3. The documented reverse for-loop folds right-to-left: summing gives the
 *      same total, and string concatenation proves the right-to-left order.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var rrArr = [1, 2, 3, 4];
assert("DEV typeof [].reduceRight is undefined (spec ES5: function)", typeof rrArr.reduceRight, "undefined");
assertThrows("DEV [].reduceRight(fn,0) throws (spec: folds right-to-left)", function () { var a = [1]; return a.reduceRight(function (acc, x) { return acc + x; }, 0); });

var sum = 0;
for (var i = rrArr.length - 1; i >= 0; i--) {
    sum += rrArr[i];
}
assert("workaround reverse loop sums to 10", sum, "10");

var concatRight = "";
var letters = ["a", "b", "c"];
for (var j = letters.length - 1; j >= 0; j--) {
    concatRight += letters[j];
}
assert("workaround folds right-to-left -> cba", concatRight, "cba");
</script>

some

(ES5) — ❌ Missing. Use a for loop or the polyfill.

var hasLarge = false;
for (var i = 0; i < arr.length; i++) {
    if (arr[i] > 10) { hasLarge = true; break; }
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: some(fn) - MISSING
 *
 * Proves:
 *   1. Array.prototype.some is NOT available
 *      (typeof [].some is "undefined"; spec (ES5): a function).
 *   2. Calling it throws.
 *   3. The documented early-break for-loop is true when at least one item
 *      matches and false when none do.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var someArr = [1, 20, 3];
assert("DEV typeof [].some is undefined (spec ES5: function)", typeof someArr.some, "undefined");
assertThrows("DEV [].some(fn) throws (spec: returns a boolean)", function () { var a = [1]; return a.some(function (x) { return true; }); });

var hasLarge = false;
for (var i = 0; i < someArr.length; i++) {
    if (someArr[i] > 10) { hasLarge = true; break; }
}
assert("workaround some(>10) is true for [1,20,3]", hasLarge, "true");

var smallArr = [1, 2, 3];
var hasLarge2 = false;
for (var j = 0; j < smallArr.length; j++) {
    if (smallArr[j] > 10) { hasLarge2 = true; break; }
}
assert("workaround some(>10) is false for [1,2,3]", hasLarge2, "false");
</script>

every

(ES5) — ❌ Missing. Use a for loop or the polyfill.

var allLarge = true;
for (var i = 0; i < arr.length; i++) {
    if (arr[i] <= 10) { allLarge = false; break; }
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: every(fn) - MISSING
 *
 * Proves:
 *   1. Array.prototype.every is NOT available
 *      (typeof [].every is "undefined"; spec (ES5): a function).
 *   2. Calling it throws.
 *   3. The documented early-break for-loop is true only when every item
 *      matches, and false as soon as one does not.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var everyArr = [20, 30, 40];
assert("DEV typeof [].every is undefined (spec ES5: function)", typeof everyArr.every, "undefined");
assertThrows("DEV [].every(fn) throws (spec: returns a boolean)", function () { var a = [1]; return a.every(function (x) { return true; }); });

var allLarge = true;
for (var i = 0; i < everyArr.length; i++) {
    if (everyArr[i] <= 10) { allLarge = false; break; }
}
assert("workaround every(>10) is true for [20,30,40]", allLarge, "true");

var mixedArr = [20, 5, 40];
var allLarge2 = true;
for (var j = 0; j < mixedArr.length; j++) {
    if (mixedArr[j] <= 10) { allLarge2 = false; break; }
}
assert("workaround every(>10) is false for [20,5,40]", allLarge2, "false");
</script>

find

(ES6) — ❌ Missing. Use a for loop or the polyfill.

var found = null;
for (var i = 0; i < arr.length; i++) {
    if (arr[i].id === targetId) { found = arr[i]; break; }
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: find(fn) - MISSING
 *
 * Proves:
 *   1. Array.prototype.find is NOT available
 *      (typeof [].find is "undefined"; spec (ES6): a function).
 *   2. Calling it throws.
 *   3. The documented early-break for-loop returns the matching item, and
 *      leaves the result null when nothing matches.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var fArr = [{ id: 1 }, { id: 7 }, { id: 9 }];
assert("DEV typeof [].find is undefined (spec ES6: function)", typeof fArr.find, "undefined");
assertThrows("DEV [].find(fn) throws (spec: returns the first match)", function () { return fArr.find(function (x) { return true; }); });

var found = null;
for (var i = 0; i < fArr.length; i++) {
    if (fArr[i].id === 7) { found = fArr[i]; break; }
}
assert("workaround for-loop finds the matching item", found.id, "7");

var missing = null;
for (var j = 0; j < fArr.length; j++) {
    if (fArr[j].id === 99) { missing = fArr[j]; break; }
}
assert("workaround leaves null when nothing matches", missing === null, "true");
</script>

findIndex

(ES6) — ❌ Missing. Use a for loop or the polyfill.

var idx = -1;
for (var i = 0; i < arr.length; i++) {
    if (arr[i].id === targetId) { idx = i; break; }
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: findIndex(fn) - MISSING
 *
 * Proves:
 *   1. Array.prototype.findIndex is NOT available
 *      (typeof [].findIndex is "undefined"; spec (ES6): a function).
 *   2. Calling it throws.
 *   3. The documented early-break for-loop yields the index of the match,
 *      and stays at -1 when nothing matches.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var fiArr = [{ id: 1 }, { id: 7 }, { id: 9 }];
assert("DEV typeof [].findIndex is undefined (spec ES6: function)", typeof fiArr.findIndex, "undefined");
assertThrows("DEV [].findIndex(fn) throws (spec: returns an index)", function () { return fiArr.findIndex(function (x) { return true; }); });

var idx = -1;
for (var i = 0; i < fiArr.length; i++) {
    if (fiArr[i].id === 9) { idx = i; break; }
}
assert("workaround for-loop yields index 2", idx, "2");

var missIdx = -1;
for (var j = 0; j < fiArr.length; j++) {
    if (fiArr[j].id === 99) { missIdx = j; break; }
}
assert("workaround stays -1 when nothing matches", missIdx, "-1");
</script>

includes

(ES6) — ❌ Missing. Use the polyfilled indexOf (indexOf(x) !== -1) or the polyfill.

function includes(arr, value) {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] === value) { return true; }
    }
    return false;
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: includes(value) - MISSING
 *
 * Proves:
 *   1. Array.prototype.includes is NOT available
 *      (typeof [].includes is "undefined"; spec (ES6): a function).
 *   2. Calling it throws.
 *   3. The documented helper returns true for a present value and false for
 *      an absent one.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var incArr = [10, 20, 30];
assert("DEV typeof [].includes is undefined (spec ES6: function)", typeof incArr.includes, "undefined");
assertThrows("DEV [].includes(v) throws (spec: returns a boolean)", function () { return incArr.includes(10); });

function includes(a, value) {
    for (var k = 0; k < a.length; k++) {
        if (a[k] === value) { return true; }
    }
    return false;
}
assert("workaround helper is true for a present value", includes(incArr, 20), "true");
assert("workaround helper is false for an absent value", includes(incArr, 99), "false");
</script>

fill

(ES6) — ❌ Missing. Apply the polyfill, or assign in a loop.

var arr = [];
for (var i = 0; i < 5; i++) { arr.push(0); }   // [0,0,0,0,0]
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: fill(value) - MISSING
 *
 * Proves:
 *   1. Array.prototype.fill is NOT available
 *      (typeof [].fill is "undefined"; spec (ES6): a function).
 *   2. Calling it throws.
 *   3. The documented push loop builds [0,0,0,0,0].
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var fillArr = [];
assert("DEV typeof [].fill is undefined (spec ES6: function)", typeof fillArr.fill, "undefined");
assertThrows("DEV [].fill(0) throws (spec: fills the array in place)", function () { var a = [1, 2]; return a.fill(0); });

for (var i = 0; i < 5; i++) { fillArr.push(0); }
assert("workaround push loop yields 0,0,0,0,0", fillArr.join(","), "0,0,0,0,0");
assert("workaround push loop yields length 5", fillArr.length, "5");
</script>

copyWithin

(ES6) — ❌ Missing. Apply the polyfill.

Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: copyWithin(target, start) - MISSING
 *
 * Proves:
 *   1. Array.prototype.copyWithin is NOT available
 *      (typeof [].copyWithin is "undefined"; spec (ES6): a function).
 *   2. Calling it throws, so the polyfill is required.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var cwArr = [10, 20, 30];
assert("DEV typeof [].copyWithin is undefined (spec ES6: function)", typeof cwArr.copyWithin, "undefined");
assertThrows("DEV [].copyWithin(0,1) throws (spec: shifts elements in place)", function () { var a = [1, 2, 3]; return a.copyWithin(0, 1); });
</script>

entries

(ES6) — ❌ Missing. Apply the polyfill, or iterate with an index for loop reading i and arr[i].

Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: entries() - MISSING
 *
 * Proves:
 *   1. Array.prototype.entries is NOT available
 *      (typeof [].entries is "undefined"; spec (ES6): a function).
 *   2. Calling it throws.
 *   3. The documented index for-loop reproduces index/value pairs.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var enArr = [10, 20, 30];
assert("DEV typeof [].entries is undefined (spec ES6: function)", typeof enArr.entries, "undefined");
assertThrows("DEV [].entries() throws (spec: returns an iterator)", function () { return enArr.entries(); });

var pairs = "";
for (var i = 0; i < enArr.length; i++) {
    pairs += i + ":" + enArr[i] + ";";
}
assert("workaround index loop yields index/value pairs", pairs, "0:10;1:20;2:30;");
</script>

keys

(ES6) — ❌ Missing. Use a standard index for loop (for (var i = 0; i < arr.length; i++)).

Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: keys() - MISSING
 *
 * Proves:
 *   1. Array.prototype.keys is NOT available
 *      (typeof [].keys is "undefined"; spec (ES6): a function).
 *   2. Calling it throws.
 *   3. The documented index for-loop enumerates the indices.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var kArr = [10, 20, 30];
assert("DEV typeof [].keys is undefined (spec ES6: function)", typeof kArr.keys, "undefined");
assertThrows("DEV [].keys() throws (spec: returns an index iterator)", function () { return kArr.keys(); });

var ks = "";
for (var i = 0; i < kArr.length; i++) { ks += i; }
assert("workaround index loop enumerates 0,1,2", ks, "012");
</script>

values

(ES6) — ❌ Missing. Use a standard index for loop reading arr[i].

Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: values() - MISSING
 *
 * Proves:
 *   1. Array.prototype.values is NOT available
 *      (typeof [].values is "undefined"; spec (ES6): a function).
 *   2. Calling it throws.
 *   3. The documented index for-loop reads every value via arr[i].
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var vArr = [10, 20, 30];
assert("DEV typeof [].values is undefined (spec ES6: function)", typeof vArr.values, "undefined");
assertThrows("DEV [].values() throws (spec: returns a value iterator)", function () { return vArr.values(); });

var vs = "";
for (var i = 0; i < vArr.length; i++) { vs += vArr[i] + ","; }
assert("workaround index loop reads every value", vs, "10,20,30,");
</script>

at

(ES6) — ❌ Missing. Use arr[i], and arr[arr.length + i] for negative i.

var arr = [10, 20, 30];
arr[0];                   // 10  (arr.at(0))
arr[arr.length - 1];      // 30  (arr.at(-1))
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: at(index) - MISSING
 *
 * Proves:
 *   1. Array.prototype.at is NOT available
 *      (typeof [].at is "undefined"; spec (ES6+): a function).
 *   2. Calling it throws.
 *   3. The documented substitutes arr[0] and arr[arr.length - 1] return the
 *      values at(0) and at(-1) would.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var atArr = [10, 20, 30];
assert("DEV typeof [].at is undefined (spec: function)", typeof atArr.at, "undefined");
assertThrows("DEV [].at(0) throws (spec: returns the item at an index)", function () { return atArr.at(0); });

assert("workaround arr[0] equals at(0)", atArr[0], "10");
assert("workaround arr[arr.length - 1] equals at(-1)", atArr[atArr.length - 1], "30");
</script>

flat

(ES6) — ❌ Missing. Concatenate nested arrays manually in a loop.

function flatten(arr) {
    var result = [];
    for (var i = 0; i < arr.length; i++) {
        if (typeof arr[i] === "object" && arr[i].length !== undefined) {
            for (var j = 0; j < arr[i].length; j++) { result.push(arr[i][j]); }
        } else {
            result.push(arr[i]);
        }
    }
    return result;
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: flat() - MISSING
 *
 * Proves:
 *   1. Array.prototype.flat is NOT available
 *      (typeof [].flat is "undefined"; spec (ES6+): a function).
 *   2. Calling it throws.
 *   3. The documented flatten() helper turns [1,[2,3],4] into [1,2,3,4].
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var nested = [1, [2, 3], 4];
assert("DEV typeof [].flat is undefined (spec: function)", typeof nested.flat, "undefined");
assertThrows("DEV [].flat() throws (spec: flattens nested arrays)", function () { return nested.flat(); });

function flatten(a) {
    var result = [];
    for (var i = 0; i < a.length; i++) {
        if (typeof a[i] === "object" && a[i].length !== undefined) {
            for (var j = 0; j < a[i].length; j++) { result.push(a[i][j]); }
        } else {
            result.push(a[i]);
        }
    }
    return result;
}
assert("workaround flatten() yields 1,2,3,4", flatten(nested).join(","), "1,2,3,4");
assert("workaround flatten() yields length 4", flatten(nested).length, "4");
</script>

flatMap

(ES6) — ❌ Missing. Build the result with a for loop and push.

var result = [];
for (var i = 0; i < arr.length; i++) {
    var mapped = transform(arr[i]);   // returns an array
    for (var j = 0; j < mapped.length; j++) { result.push(mapped[j]); }
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: flatMap(fn) - MISSING
 *
 * Proves:
 *   1. Array.prototype.flatMap is NOT available
 *      (typeof [].flatMap is "undefined"; spec (ES6+): a function).
 *   2. Calling it throws.
 *   3. The documented nested for-loop with push flattens the mapped arrays.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var fmArr = [10, 20, 30];
assert("DEV typeof [].flatMap is undefined (spec: function)", typeof fmArr.flatMap, "undefined");
assertThrows("DEV [].flatMap(fn) throws (spec: maps then flattens)", function () { return fmArr.flatMap(function (x) { return [x]; }); });

function transform(x) { return [x, x * 2]; }
var fmResult = [];
for (var i = 0; i < fmArr.length; i++) {
    var mapped = transform(fmArr[i]);
    for (var j = 0; j < mapped.length; j++) { fmResult.push(mapped[j]); }
}
assert("workaround nested loop flattens the mapped arrays", fmResult.join(","), "10,20,20,40,30,60");
</script>

findLast

(ES6) — ❌ Missing. Iterate from the end with a for loop.

var found = null;
for (var i = arr.length - 1; i >= 0; i--) {
    if (predicate(arr[i])) { found = arr[i]; break; }
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: findLast(fn) - MISSING
 *
 * Proves:
 *   1. Array.prototype.findLast is NOT available
 *      (typeof [].findLast is "undefined"; spec (ES6+): a function).
 *   2. Calling it throws.
 *   3. The documented reverse for-loop returns the LAST match, and leaves
 *      the result null when nothing matches.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

var flArr = [10, 20, 30];
assert("DEV typeof [].findLast is undefined (spec: function)", typeof flArr.findLast, "undefined");
assertThrows("DEV [].findLast(fn) throws (spec: returns the last match)", function () { return flArr.findLast(function (x) { return true; }); });

var lastFound = null;
for (var i = flArr.length - 1; i >= 0; i--) {
    if (flArr[i] >= 20) { lastFound = flArr[i]; break; }
}
assert("workaround reverse loop returns the LAST match", lastFound, "30");

var lastMiss = null;
for (var j = flArr.length - 1; j >= 0; j--) {
    if (flArr[j] > 999) { lastMiss = flArr[j]; break; }
}
assert("workaround leaves null when nothing matches", lastMiss === null, "true");
</script>

Array.isArray

(ES5) — ❌ Missing. Apply the polyfill.

function isArray(value) {
    return Object.prototype.toString.call(value) === "[object Array]";
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: Array.isArray(value) - MISSING
 *
 * Proves:
 *   1. Array.isArray is NOT available
 *      (typeof Array.isArray is "undefined"; spec (ES5): a function).
 *   2. Calling it throws.
 *   3. The documented Object.prototype.toString helper is true for arrays and
 *      false for plain objects and strings.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

assert("DEV typeof Array.isArray is undefined (spec ES5: function)", typeof Array.isArray, "undefined");
assertThrows("DEV Array.isArray([]) throws (spec: returns a boolean)", function () { return Array.isArray([]); });

function isArray(value) {
    return Object.prototype.toString.call(value) === "[object Array]";
}
assert("workaround is true for an array", isArray([1, 2]), "true");
assert("workaround is false for a plain object", isArray({ a: 1 }), "false");
assert("workaround is false for a string", isArray("x"), "false");
</script>

Array.of

(ES6) — ❌ Missing. Apply the polyfill, or build an array literal directly.

Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: Array.of(...) - MISSING
 *
 * Proves:
 *   1. Array.of is NOT available
 *      (typeof Array.of is "undefined"; spec (ES6): a function).
 *   2. Calling it throws.
 *   3. The documented array literal builds the same array.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

assert("DEV typeof Array.of is undefined (spec ES6: function)", typeof Array.of, "undefined");
assertThrows("DEV Array.of(1,2,3) throws (spec: builds an array of the args)", function () { return Array.of(1, 2, 3); });

var literal = [1, 2, 3];
assert("workaround array literal builds the same array", literal.join(","), "1,2,3");
</script>

Array.from

(ES6) — ❌ Missing. Build the array with a for loop over the source.

var arr = [];
for (var i = 0; i < source.length; i++) { arr.push(source[i]); }
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: Array.from(source) - MISSING
 *
 * Proves:
 *   1. Array.from is NOT available
 *      (typeof Array.from is "undefined"; spec (ES6): a function).
 *   2. Calling it throws.
 *   3. The documented push loop copies the source into a NEW array.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}

assert("DEV typeof Array.from is undefined (spec ES6: function)", typeof Array.from, "undefined");
assertThrows("DEV Array.from([1,2]) throws (spec: builds an array from a source)", function () { return Array.from([1, 2]); });

var source = [7, 8, 9];
var copy = [];
for (var i = 0; i < source.length; i++) { copy.push(source[i]); }
assert("workaround push loop copies the source", copy.join(","), "7,8,9");
assert("workaround yields a NEW array, not the source", copy === source, "false");
</script>

toReversed / toSorted / toSpliced

Missing natively. toReversed, toSorted and toSpliced are each undefined and each direct call throws in the tested contexts.

These findings concern only the three named methods. The existing slice, sort and splice behavior and caveats are unchanged.

Run each test in a separate fresh CloudPage request so Core versions are not mixed.

Show test script — before Core
<script runat="server">
/* Chapter: Array native absence before Core.
 * Proves: 1. toReversed, toSorted and toSpliced have typeof undefined.
 *         2. Each direct call throws (spec: returns an array).
 * EXPECTED OUTPUT: every assertion line starts with PASS; markers bracket execution.
 * Run in a fresh CloudPage request without loading Core or installing polyfills.
 */
/** Run the isolated chapter. @returns {void} */
(function () {
function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}
Platform.Response.Write("START Array unicorn-native-absence-precore\n");
/* 1. Resolve each native member lazily; lookup failures are separate failures. */
try {
    /** Read the native member type. @returns {string} */
    var reversedType = (function () { return typeof [1,2,3].toReversed; })();
    assert("DEV Array.toReversed precore typeof undefined (spec: function)", reversedType, "undefined");
} catch (ex) { Platform.Response.Write("FAIL Array.toReversed precore typeof lookup threw\n"); }
try {
    /** Read the native member type. @returns {string} */
    var sortedType = (function () { return typeof [10,2,1].toSorted; })();
    assert("DEV Array.toSorted precore typeof undefined (spec: function)", sortedType, "undefined");
} catch (ex) { Platform.Response.Write("FAIL Array.toSorted precore typeof lookup threw\n"); }
try {
    /** Read the native member type. @returns {string} */
    var splicedType = (function () { return typeof [1,2,3].toSpliced; })();
    assert("DEV Array.toSpliced precore typeof undefined (spec: function)", splicedType, "undefined");
} catch (ex) { Platform.Response.Write("FAIL Array.toSpliced precore typeof lookup threw\n"); }
/* 2. Invoke only inside the canonical exception helper. */
assertThrows("DEV Array.toReversed precore call throws (spec: array)",
    /** Invoke the native member. @returns {Array} */
    function () { return [1,2,3].toReversed(); });
assertThrows("DEV Array.toSorted precore call throws (spec: array)",
    /** Invoke the native member. @returns {Array} */
    function () { return [10,2,1].toSorted(); });
assertThrows("DEV Array.toSpliced precore call throws (spec: array)",
    /** Invoke the native member. @returns {Array} */
    function () { return [1,2,3].toSpliced(1,1,9); });
Platform.Response.Write("END Array unicorn-native-absence-precore\n");
})();
</script>

Show test script — Core 1.1.1
<script runat="server">
/* Chapter: Array native absence with Core 1.1.1.
 * Proves: 1. toReversed, toSorted and toSpliced have typeof undefined.
 *         2. Each direct call throws (spec: returns an array).
 * EXPECTED OUTPUT: every assertion line starts with PASS; markers bracket execution.
 * Run in a fresh CloudPage request without other Core versions or polyfills.
 * All six CORE LOAD OK markers are required; load failure is not member evidence.
 */
/** Run the isolated chapter. @returns {void} */
(function () {
function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}
Platform.Response.Write("START Array unicorn-native-absence-core111\n");
/* 1. Load and resolve each member in the same thunk. */
try {
    /** Load Core and read the native member type. @returns {string} */
    var reversedType = (function () {
        Platform.Load("core", "1.1.1");
        Platform.Response.Write("CORE LOAD OK Array.toReversed core111 typeof\n");
        return typeof [1,2,3].toReversed;
    })();
    assert("DEV Array.toReversed core111 typeof undefined (spec: function)", reversedType, "undefined");
} catch (ex) { Platform.Response.Write("FAIL Array.toReversed core111 load or typeof lookup threw\n"); }
try {
    /** Load Core and read the native member type. @returns {string} */
    var sortedType = (function () {
        Platform.Load("core", "1.1.1");
        Platform.Response.Write("CORE LOAD OK Array.toSorted core111 typeof\n");
        return typeof [10,2,1].toSorted;
    })();
    assert("DEV Array.toSorted core111 typeof undefined (spec: function)", sortedType, "undefined");
} catch (ex) { Platform.Response.Write("FAIL Array.toSorted core111 load or typeof lookup threw\n"); }
try {
    /** Load Core and read the native member type. @returns {string} */
    var splicedType = (function () {
        Platform.Load("core", "1.1.1");
        Platform.Response.Write("CORE LOAD OK Array.toSpliced core111 typeof\n");
        return typeof [1,2,3].toSpliced;
    })();
    assert("DEV Array.toSpliced core111 typeof undefined (spec: function)", splicedType, "undefined");
} catch (ex) { Platform.Response.Write("FAIL Array.toSpliced core111 load or typeof lookup threw\n"); }
/* 2. Load failures must not satisfy a member's call-throws assertion. */
assertThrows("DEV Array.toReversed core111 call throws (spec: array)",
    /** Load Core and invoke the native member. @returns {Array} */
    function () {
        try { Platform.Load("core", "1.1.1"); }
        catch (ex) { Platform.Response.Write("FAIL Array.toReversed core111 call Core load\n"); return; }
        Platform.Response.Write("CORE LOAD OK Array.toReversed core111 call\n");
        return [1,2,3].toReversed();
    });
assertThrows("DEV Array.toSorted core111 call throws (spec: array)",
    /** Load Core and invoke the native member. @returns {Array} */
    function () {
        try { Platform.Load("core", "1.1.1"); }
        catch (ex) { Platform.Response.Write("FAIL Array.toSorted core111 call Core load\n"); return; }
        Platform.Response.Write("CORE LOAD OK Array.toSorted core111 call\n");
        return [10,2,1].toSorted();
    });
assertThrows("DEV Array.toSpliced core111 call throws (spec: array)",
    /** Load Core and invoke the native member. @returns {Array} */
    function () {
        try { Platform.Load("core", "1.1.1"); }
        catch (ex) { Platform.Response.Write("FAIL Array.toSpliced core111 call Core load\n"); return; }
        Platform.Response.Write("CORE LOAD OK Array.toSpliced core111 call\n");
        return [1,2,3].toSpliced(1,1,9);
    });
Platform.Response.Write("END Array unicorn-native-absence-core111\n");
})();
</script>

Show test script — Core 1.1.5
<script runat="server">
/* Chapter: Array native absence with Core 1.1.5.
 * Proves: 1. toReversed, toSorted and toSpliced have typeof undefined.
 *         2. Each direct call throws (spec: returns an array).
 * EXPECTED OUTPUT: every assertion line starts with PASS; markers bracket execution.
 * Run in a fresh CloudPage request without other Core versions or polyfills.
 * All six CORE LOAD OK markers are required; load failure is not member evidence.
 */
/** Run the isolated chapter. @returns {void} */
(function () {
function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}
Platform.Response.Write("START Array unicorn-native-absence-core115\n");
/* 1. Load and resolve each member in the same thunk. */
try {
    /** Load Core and read the native member type. @returns {string} */
    var reversedType = (function () {
        Platform.Load("core", "1.1.5");
        Platform.Response.Write("CORE LOAD OK Array.toReversed core115 typeof\n");
        return typeof [1,2,3].toReversed;
    })();
    assert("DEV Array.toReversed core115 typeof undefined (spec: function)", reversedType, "undefined");
} catch (ex) { Platform.Response.Write("FAIL Array.toReversed core115 load or typeof lookup threw\n"); }
try {
    /** Load Core and read the native member type. @returns {string} */
    var sortedType = (function () {
        Platform.Load("core", "1.1.5");
        Platform.Response.Write("CORE LOAD OK Array.toSorted core115 typeof\n");
        return typeof [10,2,1].toSorted;
    })();
    assert("DEV Array.toSorted core115 typeof undefined (spec: function)", sortedType, "undefined");
} catch (ex) { Platform.Response.Write("FAIL Array.toSorted core115 load or typeof lookup threw\n"); }
try {
    /** Load Core and read the native member type. @returns {string} */
    var splicedType = (function () {
        Platform.Load("core", "1.1.5");
        Platform.Response.Write("CORE LOAD OK Array.toSpliced core115 typeof\n");
        return typeof [1,2,3].toSpliced;
    })();
    assert("DEV Array.toSpliced core115 typeof undefined (spec: function)", splicedType, "undefined");
} catch (ex) { Platform.Response.Write("FAIL Array.toSpliced core115 load or typeof lookup threw\n"); }
/* 2. Load failures must not satisfy a member's call-throws assertion. */
assertThrows("DEV Array.toReversed core115 call throws (spec: array)",
    /** Load Core and invoke the native member. @returns {Array} */
    function () {
        try { Platform.Load("core", "1.1.5"); }
        catch (ex) { Platform.Response.Write("FAIL Array.toReversed core115 call Core load\n"); return; }
        Platform.Response.Write("CORE LOAD OK Array.toReversed core115 call\n");
        return [1,2,3].toReversed();
    });
assertThrows("DEV Array.toSorted core115 call throws (spec: array)",
    /** Load Core and invoke the native member. @returns {Array} */
    function () {
        try { Platform.Load("core", "1.1.5"); }
        catch (ex) { Platform.Response.Write("FAIL Array.toSorted core115 call Core load\n"); return; }
        Platform.Response.Write("CORE LOAD OK Array.toSorted core115 call\n");
        return [10,2,1].toSorted();
    });
assertThrows("DEV Array.toSpliced core115 call throws (spec: array)",
    /** Load Core and invoke the native member. @returns {Array} */
    function () {
        try { Platform.Load("core", "1.1.5"); }
        catch (ex) { Platform.Response.Write("FAIL Array.toSpliced core115 call Core load\n"); return; }
        Platform.Response.Write("CORE LOAD OK Array.toSpliced core115 call\n");
        return [1,2,3].toSpliced(1,1,9);
    });
Platform.Response.Write("END Array unicorn-native-absence-core115\n");
})();
</script>

findLastIndex

Missing natively. findLastIndex is undefined and a direct call with [1,2,1] and a predicate matching 1 throws in the tested contexts.

Show test script — before Core
<script runat="server">
/* Chapter: findLastIndex native absence before Core.
 * Derived from runtime evidence 2026-09-06; assertion script statically checked, not executed live
 * Checks: 1. Native member has typeof undefined. 2. Direct call throws.
 * EXPECTED OUTPUT: two PASS assertion lines (expectation only), plus START/END markers.
 * Run alone in a fresh CloudPage request without Core or polyfills.
 */
/** Run the isolated chapter. @returns {void} Writes assertion results. */
(function () {
function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}
Platform.Response.Write("START findLastIndex precore\n");
/* 1. Guard the native member lookup. */
try {
    /** Read the native member type. @returns {string} Member type. */
    var memberType = (function () { return typeof [1,2,1].findLastIndex; })();
    assert("DEV findLastIndex precore typeof undefined (spec: function)", memberType, "undefined");
} catch (ex) { Platform.Response.Write("FAIL findLastIndex precore typeof lookup threw\n"); }
/* 2. Invoke only inside the canonical exception helper. */
assertThrows("DEV findLastIndex precore call throws (spec: index)",
    /** Invoke the native member. @returns {number} Index if callable. */
    function () {
        return [1,2,1].findLastIndex(
            /** Match one. @param {number} item - Candidate. @returns {boolean} Whether it equals one. */
            function (item) { return item === 1; });
    });
Platform.Response.Write("END findLastIndex precore\n");
})();
</script>

Show test script — Core 1.1.1
<script runat="server">
/* Chapter: findLastIndex native absence with Core 1.1.1.
 * Derived from runtime evidence 2026-09-06; assertion script statically checked, not executed live
 * Checks: 1. Native member has typeof undefined. 2. Direct call throws.
 * EXPECTED OUTPUT: two PASS assertion lines (expectation only), plus START/END markers.
 * Run alone in a fresh CloudPage request without other Core versions or polyfills.
 * Both CORE LOAD OK markers are required; load failure is not member evidence.
 */
/** Run the isolated chapter. @returns {void} Writes assertion results. */
(function () {
function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}
Platform.Response.Write("START findLastIndex core111\n");
/* 1. Load and resolve the member in the same guarded thunk. */
try {
    /** Load Core and read the native member type. @returns {string} Member type. */
    var memberType = (function () {
        Platform.Load("core", "1.1.1");
        Platform.Response.Write("CORE LOAD OK findLastIndex core111 typeof\n");
        return typeof [1,2,1].findLastIndex;
    })();
    assert("DEV findLastIndex core111 typeof undefined (spec: function)", memberType, "undefined");
} catch (ex) { Platform.Response.Write("FAIL findLastIndex core111 load or typeof lookup threw\n"); }
/* 2. A failed Core load must not satisfy the call-throws assertion. */
assertThrows("DEV findLastIndex core111 call throws (spec: index)",
    /** Load Core and invoke the native member. @returns {number|undefined} Index if callable. */
    function () {
        try { Platform.Load("core", "1.1.1"); }
        catch (ex) { Platform.Response.Write("FAIL findLastIndex core111 call Core load\n"); return; }
        Platform.Response.Write("CORE LOAD OK findLastIndex core111 call\n");
        return [1,2,1].findLastIndex(
            /** Match one. @param {number} item - Candidate. @returns {boolean} Whether it equals one. */
            function (item) { return item === 1; });
    });
Platform.Response.Write("END findLastIndex core111\n");
})();
</script>

Show test script — Core 1.1.5
<script runat="server">
/* Chapter: findLastIndex native absence with Core 1.1.5.
 * Derived from runtime evidence 2026-09-06; assertion script statically checked, not executed live
 * Checks: 1. Native member has typeof undefined. 2. Direct call throws.
 * EXPECTED OUTPUT: two PASS assertion lines (expectation only), plus START/END markers.
 * Run alone in a fresh CloudPage request without other Core versions or polyfills.
 * Both CORE LOAD OK markers are required; load failure is not member evidence.
 */
/** Run the isolated chapter. @returns {void} Writes assertion results. */
(function () {
function assert(id, actual, expected) {
    var got;
    try { got = String(actual); } catch (ex) { got = "THREW: " + ex.message; }
    Platform.Response.Write((got === String(expected) ? "PASS " : "FAIL ") + id + " -> [" + got + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}
Platform.Response.Write("START findLastIndex core115\n");
/* 1. Load and resolve the member in the same guarded thunk. */
try {
    /** Load Core and read the native member type. @returns {string} Member type. */
    var memberType = (function () {
        Platform.Load("core", "1.1.5");
        Platform.Response.Write("CORE LOAD OK findLastIndex core115 typeof\n");
        return typeof [1,2,1].findLastIndex;
    })();
    assert("DEV findLastIndex core115 typeof undefined (spec: function)", memberType, "undefined");
} catch (ex) { Platform.Response.Write("FAIL findLastIndex core115 load or typeof lookup threw\n"); }
/* 2. A failed Core load must not satisfy the call-throws assertion. */
assertThrows("DEV findLastIndex core115 call throws (spec: index)",
    /** Load Core and invoke the native member. @returns {number|undefined} Index if callable. */
    function () {
        try { Platform.Load("core", "1.1.5"); }
        catch (ex) { Platform.Response.Write("FAIL findLastIndex core115 call Core load\n"); return; }
        Platform.Response.Write("CORE LOAD OK findLastIndex core115 call\n");
        return [1,2,1].findLastIndex(
            /** Match one. @param {number} item - Candidate. @returns {boolean} Whether it equals one. */
            function (item) { return item === 1; });
    });
Platform.Response.Write("END findLastIndex core115\n");
})();
</script>

See Also