mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-02 08:35:07 +08:00
Expand static native object and array semantics (#569)
* Support primitive and function property descriptors * Dispatch literal bracket calls to native class methods * Handle numeric class method keys in bracket calls * Call function values returned by class accessors * Expand native object and array semantics * Keep new corpus fixtures aligned with compiler gates * Lower Object.isFrozen arguments once
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
let reads = 0;
|
||||
class Provider {
|
||||
get callable() {
|
||||
reads++;
|
||||
return function(value) { return value + 1; };
|
||||
}
|
||||
}
|
||||
const provider = new Provider();
|
||||
console.log(provider.callable(4), reads);
|
||||
class PrivateProvider {
|
||||
#method(value = 2) { return value + 3; }
|
||||
get method() { return this.#method; }
|
||||
}
|
||||
console.log(new PrivateProvider().method());
|
||||
@@ -0,0 +1,19 @@
|
||||
class Base {
|
||||
value() { return 'base'; }
|
||||
}
|
||||
class Derived extends Base {
|
||||
value() { return 'derived'; }
|
||||
}
|
||||
const base = new Base();
|
||||
const derived = new Derived();
|
||||
console.log(base['value'](), derived['value']());
|
||||
let asBase = derived;
|
||||
console.log(asBase['value']());
|
||||
class Keyword {
|
||||
w\u0069th() { return 42; }
|
||||
}
|
||||
console.log(new Keyword()['with']());
|
||||
class Numeric {
|
||||
[7]() { return 'seven'; }
|
||||
}
|
||||
console.log(new Numeric()[7]());
|
||||
@@ -0,0 +1,13 @@
|
||||
const record = { 0: 2, 1: 4, 2: 6, length: 3 };
|
||||
console.log(Array.prototype.findLast.call(record, value => value < 6));
|
||||
console.log(Array.prototype.findLastIndex.call(record, value => value < 6));
|
||||
console.log(Array.prototype.findLast.call(record, value => value > 9));
|
||||
console.log(Array.prototype.findLastIndex.call(record, value => value > 9));
|
||||
|
||||
const sparse = { 0: 1, 2: 3, length: 3 };
|
||||
const seen = [];
|
||||
console.log(Array.prototype.findLastIndex.call(sparse, (value, index) => {
|
||||
seen.push(`${index}:${value}`);
|
||||
return value === undefined;
|
||||
}));
|
||||
console.log(seen.join(','));
|
||||
@@ -0,0 +1,13 @@
|
||||
const arrayLike = { 0: 'a', 1: 'b', 2: 'c', 3: 'd', length: 4 };
|
||||
console.log(Array.prototype.slice.call(arrayLike).join(','));
|
||||
console.log(Array.prototype.slice.call(arrayLike, 1, 3).join(','));
|
||||
console.log(Array.prototype.slice.call(arrayLike, -2).join(','));
|
||||
console.log(Array.prototype.slice.call(arrayLike, 0, -1).join(','));
|
||||
console.log(Array.prototype.slice.call(arrayLike, 8).length);
|
||||
console.log(Array.prototype.slice.call(arrayLike, -9, 2).join(','));
|
||||
console.log(Array.prototype.slice.call(arrayLike, 3, 1).length);
|
||||
console.log(Array.prototype.slice.call(arrayLike, 1, undefined).join(','));
|
||||
|
||||
const values = JSON.parse('[1,2,3,4]');
|
||||
console.log(Array.prototype.slice.call(values, -3, -1).join(','));
|
||||
console.log(values.join(','));
|
||||
@@ -0,0 +1,15 @@
|
||||
const values = JSON.parse('[4,1,3,2]');
|
||||
console.log(values.toReversed().join(','), values.join(','));
|
||||
console.log(values.toSorted().join(','), values.join(','));
|
||||
console.log(values.toSorted((a, b) => b - a).join(','));
|
||||
console.log(values.toSpliced(1, 2, 8, 9).join(','), values.join(','));
|
||||
console.log(values.toSpliced(-2, 1).join(','));
|
||||
console.log(values.with(-1, 7).join(','), values.join(','));
|
||||
try { values.with(9, 0); } catch (error) { console.log(error.name); }
|
||||
|
||||
Object.freeze(values);
|
||||
console.log(values.toReversed().join(','));
|
||||
console.log(values.toSorted().join(','));
|
||||
console.log(values.toSpliced(0, 1, 6).join(','));
|
||||
console.log(values.with(0, 5).join(','));
|
||||
console.log(values.join(','));
|
||||
@@ -0,0 +1,17 @@
|
||||
const values = JSON.parse('[1,2,3,4,5]');
|
||||
console.log(values.fill(8, 1, -1) === values, values.join(','));
|
||||
console.log(values.copyWithin(2, 0, 3) === values, values.join(','));
|
||||
console.log(values.copyWithin(0, 2, 5).join(','));
|
||||
console.log(values.copyWithin(-2, 0, 2).join(','));
|
||||
|
||||
const frozen = JSON.parse('[1,2,3]');
|
||||
Object.freeze(frozen);
|
||||
try { frozen.fill(9); } catch (error) { console.log(error.name); }
|
||||
try { frozen.copyWithin(1, 0); } catch (error) { console.log(error.name); }
|
||||
console.log(frozen.join(','));
|
||||
|
||||
const sealed = JSON.parse('[1,2,3]');
|
||||
Object.seal(sealed);
|
||||
sealed.fill(7, 1);
|
||||
sealed.copyWithin(0, 1);
|
||||
console.log(sealed.join(','));
|
||||
@@ -0,0 +1,21 @@
|
||||
const empty = JSON.parse('[]');
|
||||
Object.freeze(empty);
|
||||
console.log(empty.sort().length, empty.reverse().length);
|
||||
console.log(empty.fill(4).length, empty.copyWithin(0, 0).length);
|
||||
for (const operation of [() => empty.push(), () => empty.pop(), () => empty.shift(), () => empty.unshift(), () => empty.splice(0, 0)]) {
|
||||
try { operation(); } catch (error) { console.log(error.name); }
|
||||
}
|
||||
|
||||
const one = JSON.parse('[1]');
|
||||
Object.freeze(one);
|
||||
console.log(one.sort().join(','), one.reverse().join(','));
|
||||
console.log(one.fill(9, 0, 0).join(','), one.copyWithin(0, 1).join(','));
|
||||
try { one.fill(9); } catch (error) { console.log(error.name); }
|
||||
try { one.copyWithin(0, 0); } catch (error) { console.log(error.name); }
|
||||
console.log(one.join(','));
|
||||
|
||||
const two = JSON.parse('[2,1]');
|
||||
Object.freeze(two);
|
||||
try { two.sort(); } catch (error) { console.log(error.name); }
|
||||
try { two.reverse(); } catch (error) { console.log(error.name); }
|
||||
console.log(two.join(','));
|
||||
@@ -0,0 +1,28 @@
|
||||
const values = JSON.parse('[4,2,4,1]');
|
||||
console.log(values.indexOf(4), values.indexOf(4, 1), values.indexOf(4, -2));
|
||||
console.log(values.lastIndexOf(4), values.lastIndexOf(4, 1), values.lastIndexOf(4, -3));
|
||||
console.log(values.includes(4, 3), values.includes(4, -2), values.includes(4, Infinity));
|
||||
console.log(values.findLast((value) => value > 1), values.findLastIndex((value) => value > 1));
|
||||
console.log(values.findLast((value) => value > 9), values.findLastIndex((value) => value > 9));
|
||||
console.log(values.slice(-3, -1).join(','), values.slice(99).join(','));
|
||||
console.log(values.toReversed().join(','), values.join(','));
|
||||
console.log(values.toSpliced(0, 0, 8).join(','), values.join(','));
|
||||
console.log(values.with(-4, 7).join(','), values.join(','));
|
||||
|
||||
const shifted = JSON.parse('[1,2,3]');
|
||||
console.log(shifted.unshift(8, 9), shifted.join(','));
|
||||
console.log(shifted.unshift(), shifted.join(','));
|
||||
console.log(shifted.splice(1, 2, 4, 5, 6).join(','), shifted.join(','));
|
||||
console.log(shifted.splice(-1, 1, 7).join(','), shifted.join(','));
|
||||
|
||||
const copied = JSON.parse('[0,1,2,3,4]');
|
||||
console.log(copied.copyWithin(1, 3).join(','));
|
||||
console.log(copied.copyWithin(-2, 0, 2).join(','));
|
||||
console.log(copied.fill(6, -3, -1).join(','));
|
||||
console.log(copied.fill(7, 0, 0).join(','));
|
||||
|
||||
const nested = JSON.parse('[1,[2,[3]],4]');
|
||||
console.log(nested.flat(0).join(','));
|
||||
console.log(nested.flat(1).join(','));
|
||||
console.log(nested.flat(2).join(','));
|
||||
console.log(JSON.stringify(nested));
|
||||
@@ -0,0 +1,27 @@
|
||||
const sealed = JSON.parse('[1,2]');
|
||||
Object.seal(sealed);
|
||||
console.log(Object.isExtensible(sealed), Object.isSealed(sealed), Object.isFrozen(sealed));
|
||||
console.log(Object.getOwnPropertyDescriptor(sealed, '0').configurable);
|
||||
console.log(Object.getOwnPropertyDescriptor(sealed, '0').writable);
|
||||
sealed[0] = 4;
|
||||
console.log(sealed[0]);
|
||||
for (const operation of [() => sealed.pop(), () => sealed.shift(), () => sealed.push(3)]) {
|
||||
try { operation(); } catch (error) { console.log(error.name); }
|
||||
}
|
||||
console.log(sealed.join(','));
|
||||
|
||||
const frozen = JSON.parse('[3,5]');
|
||||
Object.freeze(frozen);
|
||||
console.log(Object.isSealed(frozen), Object.isFrozen(frozen));
|
||||
console.log(Object.getOwnPropertyDescriptor(frozen, '0').writable);
|
||||
console.log(Object.getOwnPropertyDescriptor(frozen, 'length').writable);
|
||||
for (const operation of [() => { frozen[0] = 9; }, () => frozen.reverse(), () => frozen.sort()]) {
|
||||
try { operation(); } catch (error) { console.log(error.name); }
|
||||
}
|
||||
console.log(frozen.join(','));
|
||||
|
||||
const empty = JSON.parse('[]');
|
||||
Object.preventExtensions(empty);
|
||||
console.log(Object.isSealed(empty), Object.isFrozen(empty));
|
||||
try { empty.push(1); } catch (error) { console.log(error.name); }
|
||||
console.log(empty.length);
|
||||
@@ -0,0 +1,19 @@
|
||||
const values = JSON.parse('[1,2,3,4]');
|
||||
values.length = 2;
|
||||
console.log(values.length, values.join(','), Object.keys(values).join(','));
|
||||
values.length = 2;
|
||||
console.log(values.length, Object.hasOwn(values, '2'));
|
||||
values[2] = 8;
|
||||
console.log(values.join(','));
|
||||
try { values.length = -1; } catch (error) { console.log(error.name); }
|
||||
console.log(values.length);
|
||||
|
||||
const sealed = JSON.parse('[1,2,3]');
|
||||
Object.seal(sealed);
|
||||
try { sealed.length = 1; } catch (error) { console.log(error.name); }
|
||||
console.log(sealed.length, sealed.join(','));
|
||||
|
||||
const frozen = JSON.parse('[1,2]');
|
||||
Object.freeze(frozen);
|
||||
try { frozen.length = 1; } catch (error) { console.log(error.name); }
|
||||
console.log(frozen.length, frozen.join(','));
|
||||
@@ -0,0 +1,21 @@
|
||||
const values = JSON.parse('[3,5]');
|
||||
values.extra = 7;
|
||||
Object.defineProperty(values, 'hidden', { value: 9, writable: true, configurable: true });
|
||||
console.log(values.extra, values.hidden, values.length);
|
||||
console.log(Object.keys(values).join(','));
|
||||
console.log(Object.getOwnPropertyNames(values).join(','));
|
||||
console.log(Object.hasOwn(values, 'extra'), 'hidden' in values);
|
||||
console.log(Object.getOwnPropertyDescriptor(values, 'hidden').enumerable);
|
||||
console.log(Object.getOwnPropertyDescriptors(values).extra.value);
|
||||
const keys = [];
|
||||
for (const key in values) keys.push(key);
|
||||
console.log(keys.join(','));
|
||||
delete values.hidden;
|
||||
console.log(Object.hasOwn(values, 'hidden'));
|
||||
Object.seal(values);
|
||||
console.log(Object.isSealed(values), Object.isFrozen(values));
|
||||
console.log(Object.getOwnPropertyDescriptor(values, 'extra').configurable);
|
||||
values.extra = 8;
|
||||
console.log(values.extra);
|
||||
Object.freeze(values);
|
||||
console.log(Object.isFrozen(values), Object.getOwnPropertyDescriptor(values, 'extra').writable);
|
||||
@@ -0,0 +1,18 @@
|
||||
const values = JSON.parse('[1,2,3,4]');
|
||||
console.log(values.reduce((a, b) => a + b));
|
||||
console.log(values.reduceRight((a, b) => a - b));
|
||||
console.log(values.reduce((a, b) => a + b, 10));
|
||||
console.log(values.findLast(x => x < 4), values.findLastIndex(x => x < 4));
|
||||
console.log(values.findLast(x => x > 9), values.findLastIndex(x => x > 9));
|
||||
try { JSON.parse('[]').reduce((a, b) => a + b); } catch (error) { console.log(error.name); }
|
||||
console.log(JSON.parse('[]').reduce((a, b) => a + b, 5));
|
||||
console.log(JSON.parse('[7]').reduce((a, b) => a + b));
|
||||
console.log(JSON.parse('[7]').reduceRight((a, b) => a + b));
|
||||
const shrinking = JSON.parse('[1,2,3]');
|
||||
const seen = [];
|
||||
const found = shrinking.findLast((value, index) => {
|
||||
seen.push(`${index}:${value}`);
|
||||
if (index === 2) shrinking.length = 1;
|
||||
return false;
|
||||
});
|
||||
console.log(found, seen.join(','), shrinking.join(','));
|
||||
@@ -0,0 +1,11 @@
|
||||
const values = JSON.parse('[1,2,1,3]');
|
||||
console.log(values.indexOf(1), values.indexOf(1, 1), values.indexOf(1, -2));
|
||||
console.log(values.indexOf(2, 3), values.indexOf(2, -9));
|
||||
console.log(values.lastIndexOf(1), values.lastIndexOf(1, 1), values.lastIndexOf(1, -2));
|
||||
console.log(values.lastIndexOf(3, -9), values.lastIndexOf(3, 99));
|
||||
console.log(values.includes(1, 2), values.includes(1, 3), values.includes(3, -1));
|
||||
console.log(values.includes(2, 8), values.includes(2, -8));
|
||||
const empty = JSON.parse('[]');
|
||||
let conversions = 0;
|
||||
const from = { valueOf() { conversions++; return 0; } };
|
||||
console.log(empty.indexOf(1, from), empty.lastIndexOf(1, from), empty.includes(1, from), conversions);
|
||||
@@ -0,0 +1,18 @@
|
||||
const values = JSON.parse('[0,1,2,3]');
|
||||
let conversions = 0;
|
||||
const start = { valueOf() { conversions++; return 1; } };
|
||||
const count = { valueOf() { conversions++; return 2; } };
|
||||
console.log(values.splice(start, count, 8, 9).join(','));
|
||||
console.log(values.join(','), conversions);
|
||||
console.log(values.splice(-1, 0, 7).join(','), values.join(','));
|
||||
|
||||
const sealed = JSON.parse('[1,2]');
|
||||
Object.seal(sealed);
|
||||
let sealedConversions = 0;
|
||||
const sealedStart = { valueOf() { sealedConversions++; return 0; } };
|
||||
console.log(sealed.splice(sealedStart, 1, 3).join(','), sealed.join(','), sealedConversions);
|
||||
|
||||
const frozen = JSON.parse('[4,5]');
|
||||
Object.freeze(frozen);
|
||||
try { frozen.splice(0, 1); } catch (error) { console.log(error.name); }
|
||||
console.log(frozen.join(','));
|
||||
@@ -0,0 +1,18 @@
|
||||
const values = JSON.parse('[0,1,2,3,4]');
|
||||
console.log(values.splice(1, 2, 8, 9).join(','), values.join(','));
|
||||
console.log(values.splice(-2, 1).join(','), values.join(','));
|
||||
console.log(values.splice(1, 0, 7).join(','), values.join(','));
|
||||
console.log(values.splice(2).join(','), values.join(','));
|
||||
console.log(values.splice(9, 2).join(','), values.join(','));
|
||||
|
||||
const nested = JSON.parse('[1,[2,[3,[4]]],5]');
|
||||
console.log(JSON.stringify(nested.flat()));
|
||||
console.log(JSON.stringify(nested.flat(2)));
|
||||
console.log(JSON.stringify(nested.flat(0)));
|
||||
console.log(JSON.stringify(nested));
|
||||
|
||||
const sealed = JSON.parse('[1,2,3]');
|
||||
Object.seal(sealed);
|
||||
console.log(sealed.splice(1, 1, 7).join(','), sealed.join(','));
|
||||
try { sealed.splice(1, 1); } catch (error) { console.log(error.name); }
|
||||
console.log(sealed.join(','));
|
||||
@@ -0,0 +1,12 @@
|
||||
const object = JSON.parse('{"first":1,"second":2}');
|
||||
Object.defineProperty(object, 'hidden', { value: 3 });
|
||||
const descriptors = Object.getOwnPropertyDescriptors(object);
|
||||
console.log(Object.keys(descriptors).join(','));
|
||||
console.log(descriptors.first.value, descriptors.first.writable, descriptors.first.enumerable, descriptors.first.configurable);
|
||||
console.log(descriptors.hidden.value, descriptors.hidden.writable, descriptors.hidden.enumerable, descriptors.hidden.configurable);
|
||||
console.log(Object.getOwnPropertyDescriptors(3));
|
||||
console.log(Object.keys(Object.getOwnPropertyDescriptors('cat')).join(','));
|
||||
const parent = JSON.parse('{"inherited":4}');
|
||||
const child = Object.create(parent);
|
||||
child.own = 5;
|
||||
console.log(Object.keys(Object.getOwnPropertyDescriptors(child)).join(','));
|
||||
@@ -0,0 +1,11 @@
|
||||
const parent = JSON.parse('{"first":1,"second":2}');
|
||||
const child = Object.create(parent);
|
||||
console.log(Object.keys(parent).join(','));
|
||||
console.log(Object.getOwnPropertyNames(parent).join(','));
|
||||
console.log('first' in child);
|
||||
const parentKeys = [];
|
||||
for (const key in parent) parentKeys.push(key);
|
||||
console.log(parentKeys.join(','));
|
||||
const keys = [];
|
||||
for (const key in child) keys.push(key);
|
||||
console.log(keys.join(','));
|
||||
@@ -0,0 +1,50 @@
|
||||
const target = JSON.parse('{"visible":1}');
|
||||
Object.defineProperty(target, 'hidden', { value: 2, writable: true, configurable: true });
|
||||
console.log(Object.keys(target).join(','));
|
||||
const absent = JSON.parse('null');
|
||||
try { Object.prototype.propertyIsEnumerable.call(absent, 'x'); }
|
||||
catch (error) { console.log(error.name); }
|
||||
console.log(Object.getOwnPropertyNames(target).join(','));
|
||||
console.log(target.hidden, Object.hasOwn(target, 'hidden'), target.propertyIsEnumerable('hidden'));
|
||||
const first = Object.getOwnPropertyDescriptor(target, 'hidden');
|
||||
console.log(first.value, first.writable, first.enumerable, first.configurable);
|
||||
Object.defineProperty(target, 'hidden', { value: 3, enumerable: true });
|
||||
const second = Object.getOwnPropertyDescriptor(target, 'hidden');
|
||||
console.log(second.value, second.writable, second.enumerable, second.configurable);
|
||||
console.log(Object.keys(target).join(','), Object.values(target).join(','));
|
||||
|
||||
const parent = JSON.parse('{"inherited":4}');
|
||||
const child = Object.create(parent);
|
||||
const omittedDescriptors = Object.create(parent, undefined);
|
||||
console.log(omittedDescriptors.inherited, Object.getOwnPropertyNames(omittedDescriptors).length);
|
||||
Object.defineProperty(child, 'own', { value: 5, enumerable: true, writable: true, configurable: true });
|
||||
console.log(Object.keys(child).join(','), Object.getOwnPropertyNames(child).join(','));
|
||||
console.log(Object.hasOwn(child, 'inherited'), 'inherited' in child);
|
||||
const inherited = Object.getOwnPropertyDescriptor(child, 'inherited');
|
||||
console.log(inherited === undefined, child.inherited, Object.getPrototypeOf(child) === parent);
|
||||
const visited = [];
|
||||
for (const key in child) visited.push(key);
|
||||
console.log(visited.join(','));
|
||||
Object.defineProperty(child, 'inherited', { value: 6, enumerable: false, writable: true });
|
||||
const shadowed = [];
|
||||
for (const key in child) shadowed.push(key);
|
||||
console.log(child.inherited, parent.inherited, shadowed.join(','));
|
||||
|
||||
const fixed = JSON.parse('{"item":7}');
|
||||
Object.freeze(fixed);
|
||||
const frozen = Object.getOwnPropertyDescriptors(fixed);
|
||||
console.log(frozen.item.value, frozen.item.writable, frozen.item.configurable);
|
||||
console.log(Object.isExtensible(fixed), Object.isSealed(fixed), Object.isFrozen(fixed));
|
||||
try { Object.defineProperty(fixed, 'item', { value: 8 }); }
|
||||
catch (error) { console.log(error.name); }
|
||||
try { Object.defineProperty(fixed, 'new', { value: 9 }); }
|
||||
catch (error) { console.log(error.name); }
|
||||
console.log(fixed.item, Object.hasOwn(fixed, 'new'));
|
||||
|
||||
const nullProto = Object.create(null);
|
||||
nullProto.key = 10;
|
||||
console.log(Object.getPrototypeOf(nullProto) === null, Object.keys(nullProto).join(','));
|
||||
Object.preventExtensions(nullProto);
|
||||
console.log(Object.isExtensible(nullProto), Object.isSealed(nullProto), Object.isFrozen(nullProto));
|
||||
Object.seal(nullProto);
|
||||
console.log(Object.isSealed(nullProto), Object.isFrozen(nullProto));
|
||||
@@ -0,0 +1,44 @@
|
||||
const parent = JSON.parse('{"value": 1}');
|
||||
const child = Object.create(parent);
|
||||
console.log(child.value, Object.keys(child).length, Object.hasOwn(child, 'value'), 'value' in child);
|
||||
console.log(child.propertyIsEnumerable('value'), parent.propertyIsEnumerable('value'));
|
||||
parent.value = 2;
|
||||
console.log(child.value);
|
||||
child.value = 3;
|
||||
console.log(child.value, parent.value, Object.hasOwn(child, 'value'));
|
||||
const grandchild = Object.create(child);
|
||||
console.log(grandchild.value);
|
||||
Object.defineProperty(parent, 'inherited', { get: function() { return this.value + 1; }, enumerable: true });
|
||||
console.log(grandchild.inherited, Object.keys(grandchild).length);
|
||||
console.log(grandchild.propertyIsEnumerable('inherited'), parent.propertyIsEnumerable('inherited'));
|
||||
console.log(Object.getOwnPropertyNames(grandchild).length, Object.getOwnPropertyDescriptor(grandchild, 'value'));
|
||||
console.log(Object.getPrototypeOf(child) === parent, Object.getPrototypeOf(grandchild) === child);
|
||||
const inheritedKeys = [];
|
||||
for (const key in grandchild) inheritedKeys.push(key);
|
||||
console.log(inheritedKeys.join(','));
|
||||
Object.defineProperty(child, 'value', { value: 5, enumerable: false, writable: true, configurable: true });
|
||||
const shadowedKeys = [];
|
||||
for (const key in grandchild) shadowedKeys.push(key);
|
||||
console.log(grandchild.value, shadowedKeys.join(','));
|
||||
const replacement = JSON.parse('{"replacement": 8}');
|
||||
Object.setPrototypeOf(grandchild, replacement);
|
||||
console.log(Object.getPrototypeOf(grandchild) === replacement, grandchild.replacement, 'value' in grandchild);
|
||||
const descriptors = JSON.parse('{"own":{"value":11,"enumerable":true,"writable":true}}');
|
||||
const described = Object.create(replacement, descriptors);
|
||||
console.log(described.own, described.replacement, Object.keys(described).join(','));
|
||||
const locked = JSON.parse('{"first":1,"second":2}');
|
||||
console.log(Object.isExtensible(locked), Object.isSealed(locked), Object.isFrozen(locked));
|
||||
Object.preventExtensions(locked);
|
||||
console.log(Object.isExtensible(locked), Object.isSealed(locked), Object.isFrozen(locked));
|
||||
try { locked.third = 3; } catch (error) { console.log(error.name); }
|
||||
console.log(Object.hasOwn(locked, 'third'));
|
||||
const sealed = JSON.parse('{"first":1}');
|
||||
Object.seal(sealed);
|
||||
console.log(Object.isSealed(sealed), Object.isFrozen(sealed), Object.getOwnPropertyDescriptor(sealed, 'first').configurable);
|
||||
sealed.first = 4;
|
||||
console.log(sealed.first);
|
||||
const frozen = JSON.parse('{"first":1}');
|
||||
Object.freeze(frozen);
|
||||
console.log(Object.isSealed(frozen), Object.isFrozen(frozen), Object.getOwnPropertyDescriptor(frozen, 'first').writable);
|
||||
try { frozen.first = 4; } catch (error) { console.log(error.name); }
|
||||
console.log(frozen.first);
|
||||
@@ -0,0 +1,14 @@
|
||||
console.log(Object.getOwnPropertyDescriptor(true, 'x'));
|
||||
console.log(Object.getOwnPropertyDescriptor(7, 'x'));
|
||||
const text = Object.getOwnPropertyDescriptor('abc', '1');
|
||||
console.log(text.value, text.writable, text.enumerable, text.configurable);
|
||||
const length = Object.getOwnPropertyDescriptor('abc', 'length');
|
||||
console.log(length.value, length.writable, length.enumerable, length.configurable);
|
||||
function item(value) { return value; }
|
||||
item[1] = 'first';
|
||||
item[1] = 'second';
|
||||
const own = Object.getOwnPropertyDescriptor(item, '1');
|
||||
console.log(own.value, own.writable, own.enumerable, own.configurable);
|
||||
Object.defineProperty(item, 'fixed', { value: 42, enumerable: false, writable: false, configurable: false });
|
||||
const fixed = Object.getOwnPropertyDescriptor(item, 'fixed');
|
||||
console.log(item['fixed'], fixed.value, fixed.writable, fixed.enumerable, fixed.configurable);
|
||||
@@ -1,17 +1,4 @@
|
||||
// Object.create's fence battery: only the null-prototype dictionary
|
||||
// lowers in a static build (Object.create(null) — corpus 2581/2582).
|
||||
// Every other prototype is a NAMED fence, not an own-copy stand-in: Node
|
||||
// lists NO own keys on the created object (Object.keys/inspect/JSON all
|
||||
// answer empty) and mutating the prototype afterwards shows through it
|
||||
// LIVE — observations a copy answers wrong silently.
|
||||
|
||||
// A static record prototype.
|
||||
// Statically shaped records cannot serve as live checked-dynamic prototypes.
|
||||
const base = { indent: 2 };
|
||||
const viaRecord = Object.create(base);
|
||||
|
||||
// A checked-dynamic (dyn) prototype.
|
||||
const dynProto: object = JSON.parse('{"a":1}');
|
||||
const viaDyn = Object.create(dynProto);
|
||||
|
||||
// The properties-descriptor form.
|
||||
const withDescriptors = Object.create(null, { a: { value: 1, enumerable: true } });
|
||||
base.indent = 4;
|
||||
|
||||
@@ -1,26 +1,8 @@
|
||||
object-create-fences.ts:10:19 - error SC2020: 'Object.create over '{ indent: number }' prototypes' is part of the standard library types but has no scriptc lowering yet
|
||||
object-create-fences.ts:3:19 - error SC2020: 'Object.create over '{ indent: number }' prototypes' is part of the standard library types but has no scriptc lowering yet
|
||||
|
||||
9 | const base = { indent: 2 };
|
||||
10 | const viaRecord = Object.create(base);
|
||||
| ^~~~~~~~~~~~~~~~~~~
|
||||
11 |
|
||||
2 | const base = { indent: 2 };
|
||||
3 | const viaRecord = Object.create(base);
|
||||
| ^~~~~~~~~~~~~~~~~~~
|
||||
4 | base.indent = 4;
|
||||
|
||||
hint: the compiled representations have no prototype chain, and an own-copy would answer wrong observably (Node lists NO own keys on the created object, and prototype mutations show through it live) — only Object.create(null) lowers
|
||||
|
||||
object-create-fences.ts:14:16 - error SC2020: 'Object.create over 'unknown' prototypes' is part of the standard library types but has no scriptc lowering yet
|
||||
|
||||
13 | const dynProto: object = JSON.parse('{"a":1}');
|
||||
14 | const viaDyn = Object.create(dynProto);
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~
|
||||
15 |
|
||||
|
||||
hint: the compiled representations have no prototype chain, and an own-copy would answer wrong observably (Node lists NO own keys on the created object, and prototype mutations show through it live) — only Object.create(null) lowers
|
||||
|
||||
object-create-fences.ts:17:25 - error SC2020: 'Object.create with a properties-descriptor argument' is part of the standard library types but has no scriptc lowering yet
|
||||
|
||||
16 | // The properties-descriptor form.
|
||||
17 | const withDescriptors = Object.create(null, { a: { value: 1, enumerable: true } });
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
18 |
|
||||
|
||||
hint: create first, then assign: const o = Object.create(null); o.k = v
|
||||
hint: the type checker sees the full standard library, but only the supported surface compiles (https://scriptc.dev/limitations)
|
||||
Reference in New Issue
Block a user