1425bb815Sopenharmony_ci// Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci// 3425bb815Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci// you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci// You may obtain a copy of the License at 6425bb815Sopenharmony_ci// 7425bb815Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci// 9425bb815Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci// See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci// limitations under the License. 14425bb815Sopenharmony_ci 15425bb815Sopenharmony_civar obj = { 16425bb815Sopenharmony_ci prop: function() {}, 17425bb815Sopenharmony_ci foo: 'bar' 18425bb815Sopenharmony_ci}; 19425bb815Sopenharmony_ci// New properties may be added, existing properties may be changed or removed. 20425bb815Sopenharmony_ciobj.foo = 'baz'; 21425bb815Sopenharmony_ciobj.lumpy = 'woof'; 22425bb815Sopenharmony_cidelete obj.prop; 23425bb815Sopenharmony_ci 24425bb815Sopenharmony_civar o = Object.seal(obj); 25425bb815Sopenharmony_ci 26425bb815Sopenharmony_ciassert (o === obj); 27425bb815Sopenharmony_ciassert (Object.isSealed (obj) === true); 28425bb815Sopenharmony_ci 29425bb815Sopenharmony_ci// Changing property values on a sealed object still works. 30425bb815Sopenharmony_ciobj.foo = 'quux'; 31425bb815Sopenharmony_ciassert (obj.foo === 'quux'); 32425bb815Sopenharmony_ci// But you can't convert data properties to accessors, or vice versa. 33425bb815Sopenharmony_citry { 34425bb815Sopenharmony_ci Object.defineProperty(obj, 'foo', { get: function() { return 42; } }); // throws a TypeError 35425bb815Sopenharmony_ci assert (false); 36425bb815Sopenharmony_ci} catch (e) { 37425bb815Sopenharmony_ci assert (e instanceof TypeError); 38425bb815Sopenharmony_ci} 39425bb815Sopenharmony_ci 40425bb815Sopenharmony_ci// Now any changes, other than to property values, will fail. 41425bb815Sopenharmony_ciobj.quaxxor = 'the friendly duck'; // silently doesn't add the property 42425bb815Sopenharmony_cidelete obj.foo; // silently doesn't delete the property 43425bb815Sopenharmony_ci 44425bb815Sopenharmony_ciassert (obj.quaxxor === undefined); 45425bb815Sopenharmony_ciassert (obj.foo === 'quux') 46425bb815Sopenharmony_ci 47425bb815Sopenharmony_citry { 48425bb815Sopenharmony_ci // Attempted additions through Object.defineProperty will also throw. 49425bb815Sopenharmony_ci Object.defineProperty (obj, 'ohai', { value: 17 }); // throws a TypeError 50425bb815Sopenharmony_ci assert (false); 51425bb815Sopenharmony_ci} catch (e) { 52425bb815Sopenharmony_ci assert (e instanceof TypeError); 53425bb815Sopenharmony_ci} 54425bb815Sopenharmony_ci 55425bb815Sopenharmony_citry { 56425bb815Sopenharmony_ci Object.defineProperties (obj, { 'ohai' : { value: 17 } }); 57425bb815Sopenharmony_ci assert (false); 58425bb815Sopenharmony_ci} catch (e) { 59425bb815Sopenharmony_ci assert (e instanceof TypeError); 60425bb815Sopenharmony_ci} 61425bb815Sopenharmony_ci 62425bb815Sopenharmony_ciObject.defineProperty (obj, 'foo', { value: 'eit' }); 63425bb815Sopenharmony_ciassert (obj.foo === 'eit') 64425bb815Sopenharmony_ci 65425bb815Sopenharmony_ci// Objects aren't sealed by default. 66425bb815Sopenharmony_civar empty = {}; 67425bb815Sopenharmony_ciassert (Object.isSealed (empty) === false); 68425bb815Sopenharmony_ci 69425bb815Sopenharmony_ci// If you make an empty object non-extensible, it is vacuously sealed. 70425bb815Sopenharmony_ciObject.preventExtensions (empty); 71425bb815Sopenharmony_ciassert (Object.isSealed (empty) === true); 72425bb815Sopenharmony_ci 73425bb815Sopenharmony_ci// The same is not true of a non-empty object, unless its properties are all non-configurable. 74425bb815Sopenharmony_civar hasProp = { fee: 'fie foe fum' }; 75425bb815Sopenharmony_ciObject.preventExtensions (hasProp); 76425bb815Sopenharmony_ciassert (Object.isSealed (hasProp) === false); 77425bb815Sopenharmony_ci 78425bb815Sopenharmony_ci// But make them all non-configurable and the object becomes sealed. 79425bb815Sopenharmony_ciObject.defineProperty (hasProp, 'fee', { configurable: false }); 80425bb815Sopenharmony_ciassert (Object.isSealed (hasProp) === true); 81425bb815Sopenharmony_ci 82425bb815Sopenharmony_ci// The easiest way to seal an object, of course, is Object.seal. 83425bb815Sopenharmony_civar sealed = {}; 84425bb815Sopenharmony_ciObject.seal (sealed); 85425bb815Sopenharmony_ciassert (Object.isSealed (sealed) === true); 86