Last active
September 6, 2023 05:59
-
-
Save Rudxain/f40cf3f1304eaef0bad4492cdea0c8d1 to your computer and use it in GitHub Desktop.
Draft polyfill of my tc39 proposal: https://es.discourse.group/t/strictarray/1791
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
const StrictArray = (() => { | |
const | |
MAX_LEN = 2**32 - 1, | |
MAX_IDX = MAX_LEN - 1 | |
const is_neg_zero = x => x === 0 && 1 / x < 0 | |
const is_int_num = x => | |
typeof x == 'number' && x % 1 == 0 | |
const is_len = x => | |
typeof x == 'number' && | |
x >= 0 && x <= MAX_LEN && | |
!is_neg_zero(x) && | |
is_int_num(x) | |
const is_index = x => is_len(x) && x < MAX_LEN | |
const | |
Array_from = Array.from, | |
arr_from_len = (n, filler) => Array_from({length: n}, () => filler) | |
const | |
ERR_STR = 'Index is invalid or out-of-bounds', | |
ERR_LEN = 'Invalid length' | |
const lib = class StrictArray { | |
#main | |
constructor(...args) { | |
this.#main = args | |
} | |
static withLen(n, filler) { | |
if (!is_len(n)) | |
throw new RangeError(ERR_LEN) | |
return new StrictArray(...arr_from_len(n, filler)) | |
} | |
#is_own_index(i) { | |
return is_index(i) && i < this.#main.length | |
} | |
get length() { | |
return this.#main.length | |
} | |
/* // is this a bad idea? | |
set length(n) { | |
if (!is_len(n)) | |
throw new RangeError(ERR_LEN) | |
return this.#main.length = n | |
} | |
*/ | |
get(i) { | |
if (this.#is_own_index(i)) | |
return this.#main[i] | |
throw new RangeError(ERR_STR) | |
} | |
set(i, v) { | |
if (this.#is_own_index(i)) | |
return this.#main[i] = v | |
throw new RangeError(ERR_STR) | |
} | |
at(i) { | |
if (!is_int_num(i)) | |
throw new RangeError(ERR_STR) | |
if (i < 0) i += this.#main.length | |
return this.get(i) | |
} | |
setAt(i, v) { | |
if (!is_int_num(i)) | |
throw new RangeError(ERR_STR) | |
if (i < 0) i += this.#main.length | |
return this.set(i, v) | |
} | |
_get_main() {return this.#main} | |
} | |
const get_main = lib.prototype._get_main | |
delete lib.prototype._get_main; | |
for (const k of Object.getOwnPropertyNames(Array.prototype)) { | |
if (k in lib.prototype) | |
continue | |
lib.prototype[k] = function(...args) { | |
return [][k].call(get_main.call(this), ...args) | |
} | |
} | |
return lib | |
})() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment