private-class-field-on-nonextensible-objects-strict.js (2980B)
1 // |reftest| skip -- nonextensible-applies-to-private is not supported 2 'use strict'; 3 // Copyright (C) 2019 Caio Lima. All rights reserved. 4 // This code is governed by the BSD license found in the LICENSE file. 5 6 /*--- 7 description: It is not possible to add private fields on non-extensible objects 8 esid: sec-define-field 9 info: | 10 1.1 PrivateFieldAdd ( O, P, value ) 11 1. If O.[[Extensible]] is false, throw a TypeError exception. 12 ... 13 14 features: 15 - class 16 - class-fields-private 17 - class-fields-public 18 - nonextensible-applies-to-private 19 flags: [onlyStrict] 20 ---*/ 21 22 // Analogous to 23 // test/language/statements/class/subclass/private-class-field-on-nonextensible-return-override.js 24 25 class NonExtensibleBase { 26 constructor(seal) { 27 if (seal) Object.preventExtensions(this); 28 } 29 } 30 31 32 // extend superclass with private instance data field 33 class ClassWithPrivateField extends NonExtensibleBase { 34 #val; 35 36 constructor(seal) { 37 super(seal); 38 this.#val = 42; 39 } 40 val() { 41 return this.#val; 42 } 43 } 44 45 const t = new ClassWithPrivateField(false); 46 // extensible objects can be extended 47 assert.sameValue(t.val(), 42); 48 49 // where superclass prevented extensions & subclass extended 50 assert.throws(TypeError, function () { 51 new ClassWithPrivateField(true); 52 }); 53 54 55 // extend superclass with private instance method 56 class ClassWithPrivateMethod extends NonExtensibleBase { 57 constructor(seal) { 58 super(seal); 59 } 60 // private methods are on the instance, so will fail 61 #privateMethod() { 62 return 42; 63 }; 64 // public methods are on the prototype, so are ok. 65 publicMethod() { 66 return this.#privateMethod(); 67 } 68 } 69 70 const m = new ClassWithPrivateMethod(false); 71 // extensible objects can be extended 72 assert.sameValue(m.publicMethod(), 42); 73 74 // where superclass prevented extensions & subclass extended 75 assert.throws(TypeError, function () { 76 new ClassWithPrivateMethod(true); 77 }); 78 79 80 // extend superclass with private instance accessor 81 class ClassWithPrivateAccessor extends NonExtensibleBase { 82 constructor(seal) { 83 super(seal); 84 } 85 // private accessors are on the instance, so will fail 86 get #privateAccessor() { 87 return 42; 88 }; 89 // public accessors are on the prototype, so are ok. 90 get publicAccessor() { 91 return this.#privateAccessor; 92 } 93 } 94 95 const a = new ClassWithPrivateAccessor(false); 96 // extensible objects can be extended 97 assert.sameValue(a.publicAccessor, 42); 98 99 // where superclass prevented extensions & subclass extended 100 assert.throws(TypeError, function () { 101 new ClassWithPrivateAccessor(true); 102 }); 103 104 105 // base class private instance data field 106 class TestNonExtensibleData { 107 #g = (Object.preventExtensions(this), "Test262"); 108 } 109 110 assert.throws(TypeError, function () { 111 new TestNonExtensibleData(); 112 }); 113 114 // base class with private static data field 115 assert.throws(TypeError, function () { 116 class TestNonExtensibleStaticData { 117 static #g = (Object.preventExtensions(TestNonExtensibleStaticData), "Test262"); 118 } 119 }); 120 121 reportCompare(0, 0);