Patch from Raphael Speyer git-svn-id: svn://10.0.0.236/trunk@258024 18797224-902f-48f8-a5cc-f745e15eee43
204 lines
7.8 KiB
Plaintext
204 lines
7.8 KiB
Plaintext
js> load('testsrc/doctests/util.js');
|
|
|
|
js> Object.defineProperty
|
|
function defineProperty() { [native code for Object.defineProperty, arity=3] }
|
|
|
|
js> expectTypeError(function() { Object.defineProperty() });
|
|
js> expectTypeError(function() { Object.defineProperty({}) });
|
|
js> expectTypeError(function() { Object.defineProperty({}, 'p') });
|
|
js> [undefined, null, true, 1, 'hello'].forEach(function(value) {
|
|
> expectTypeError(function() { Object.defineProperty(value, 'p', {}) })
|
|
> })
|
|
|
|
js> Object.defineProperty({}, 'p', {value:1}).p
|
|
1
|
|
js> var obj = {}
|
|
js> Object.defineProperty(obj, 'a', {
|
|
> value: 1,
|
|
> enumerable: false,
|
|
> writable: false,
|
|
> configurable: false
|
|
> })
|
|
[object Object]
|
|
js> for (var p in obj) print(p); // check it has no enumerable properties
|
|
js> obj.a = 2; obj.a; // check that the property is not writable
|
|
1
|
|
js> delete obj.a; obj.a // check that the property is not deletable
|
|
1
|
|
|
|
js> var define = Object.defineProperty;
|
|
js> var describe = Object.getOwnPropertyDescriptor;
|
|
|
|
js> // when define new property with empty descriptor then default values are used for the descriptor
|
|
js> var obj = define({}, 'a', {});
|
|
js> describe(obj, 'a').toSource()
|
|
({value:undefined, writable:false, enumerable:false, configurable:false})
|
|
|
|
js> // when define new property with data descriptor then those values are used for the descriptor
|
|
js> var obj = define({}, 'a', { value: 2, writable: true });
|
|
js> var {value:v, writable:w} = describe(obj, 'a'); [v, w].toSource();
|
|
[2, true]
|
|
js> obj.a
|
|
2
|
|
|
|
js> // when define new property with accessor descriptor then those values are used for the descriptor
|
|
js> var obj = define({}, 'a', { get: function() { return 3; }, set: function(value) {} });
|
|
js> var {get:g, set:s} = describe(obj, 'a'); [g, s].toSource();
|
|
[(function () {return 3;}), (function (value) {})]
|
|
js> obj.a
|
|
3
|
|
|
|
js> // when define existing property with empty descriptor then descriptor is left unchanged
|
|
js> var descriptor = {value:1, writable:true, enumerable:true, configurable:true};
|
|
js> var obj = define({}, 'a', descriptor);
|
|
js> var obj = define(obj, 'a', {});
|
|
js> describe(obj, 'a').toSource()
|
|
({value:1, writable:true, enumerable:true, configurable:true})
|
|
|
|
js> // when define existing property with same descriptor then descriptor is left unchanged
|
|
js> var descriptor = {value:1, writable:true, enumerable:true, configurable:true};
|
|
js> var obj = define({}, 'a', descriptor);
|
|
js> var obj = define(obj, 'a', descriptor);
|
|
js> describe(obj, 'a').toSource()
|
|
({value:1, writable:true, enumerable:true, configurable:true})
|
|
|
|
js> // may not change configurable from false to true
|
|
js> expectTypeError(function() {
|
|
> var obj = define({}, 'a', {configurable : false});
|
|
> define(obj, 'a', {configurable : true});
|
|
> });
|
|
|
|
js> // may not change enumerable when configurable is false
|
|
js> expectTypeError(function() {
|
|
> var obj = define({}, 'a', {enumerable : true, configurable:false});
|
|
> define(obj, 'a', {enumerable : false});
|
|
> });
|
|
|
|
js> // may not change writable from false to true when configurable is false
|
|
js> expectTypeError(function() {
|
|
> var obj = define({}, 'a', {writable : false, configurable: false});
|
|
> define(obj, 'a', {writable : true});
|
|
> });
|
|
|
|
js> // may not change value when writable is false
|
|
js> expectTypeError(function() {
|
|
> var obj = define({}, 'a', {value : 1, writable:false});
|
|
> define(obj, 'a', {value : 2});
|
|
> });
|
|
|
|
js> // may not change getter when configurable is false
|
|
js> expectTypeError(function() {
|
|
> var obj = define({}, 'a', {get: function() { return 1 }, configurable:false});
|
|
> define(obj, 'a', {get: function() { return 1 }});
|
|
> });
|
|
|
|
js> // may not change setter when configurable is false
|
|
js> expectTypeError(function() {
|
|
> var obj = define({}, 'a', {set: function(val) {}, configurable:false});
|
|
> define(obj, 'a', {set: function(val) {}});
|
|
> });
|
|
|
|
js> // may not change from data property to accessor property when configurable is false
|
|
js> expectTypeError(function() {
|
|
> var obj = define({}, 'a', {value : 1, configurable:false});
|
|
> define(obj, 'a', {get : function() { return 1 }});
|
|
> });
|
|
|
|
js> // may not change from accessor property to data property when configurable is false
|
|
js> expectTypeError(function() {
|
|
> var obj = define({}, 'a', {get : function() { return 1 }, configurable:false});
|
|
> define(obj, 'a', {value : 1});
|
|
> });
|
|
|
|
js> // can change writable from true to false when configurable is false
|
|
js> var obj = define({}, 'a', {writable:true, configurable:false});
|
|
js> var obj = define(obj, 'a', {writable:false});
|
|
|
|
js> // can set enumerable to the same value when configurable is false
|
|
js> var obj = define({}, 'a', {enumerable:true, configurable:false});
|
|
js> var obj = define(obj, 'a', {enumerable:true});
|
|
|
|
js> // can change from data property to accessor property when configurable is true
|
|
js> var obj = define({}, 'a', {value : 1, configurable: true});
|
|
js> var obj = define(obj, 'a', {get : function() { return 4 }});
|
|
js> obj.a
|
|
4
|
|
js> describe(obj, 'a').toSource()
|
|
({enumerable:false, configurable:true, get:(function () {return 4;})})
|
|
|
|
js> // can change from accessor property to data property when configurable is true
|
|
js> var obj = define({}, 'a', {get : function() { return 2 }, configurable:true});
|
|
js> var obj = define(obj, 'a', {value : 5});
|
|
js> obj.a
|
|
5
|
|
js> describe(obj, 'a').toSource()
|
|
({value:5, writable:false, enumerable:false, configurable:true})
|
|
|
|
js> // can change enumerable and writable to true when configurable is true
|
|
js> var obj = define({}, 'a', {writable : false, enumerable : false, configurable:true});
|
|
js> var obj = define(obj, 'a', {writable : true, enumerable : true, configurable:true});
|
|
|
|
js> // can change the value if writable is true
|
|
js> var obj = define({}, 'a', {value:6, writable:true})
|
|
js> obj.a
|
|
6
|
|
js> var obj = define(obj, 'a', {value:7})
|
|
js> obj.a
|
|
7
|
|
|
|
js> // defining a new property should fail loudly when object is not extensible
|
|
js> var obj = Object.preventExtensions({});
|
|
js> expectTypeError(function() { define(obj, 'a', {value:1}) })
|
|
|
|
js> // defining new property should succeed when object is extensible
|
|
js> var obj = {}
|
|
js> Object.isExtensible(obj);
|
|
true
|
|
js> obj.a = 8; obj.a
|
|
8
|
|
|
|
js> // changing existing property should succeed when object is not extensible
|
|
js> var obj = define({}, 'a', {value:1, writable:true});
|
|
js> var obj = Object.preventExtensions(obj);
|
|
js> obj.a = 9; obj.a
|
|
9
|
|
|
|
js> // defined getters and setters must be functions
|
|
js> expectTypeError(function() { define({}, 'a', {get:1}); })
|
|
js> expectTypeError(function() { define({}, 'a', {set:1}); })
|
|
|
|
js> // make sure defineProperty works properly with numbers as ids
|
|
js> Object.defineProperty({}, 0, {value:1, enumerable:true})['0']
|
|
1
|
|
|
|
js> // make sure defineProperty works properly with arrays
|
|
js> Object.defineProperty([], 0, {value:1, enumerable:true})[0]
|
|
1
|
|
|
|
js> // make sure defineProperty works properly with arrays
|
|
js> Object.defineProperty([], 'a', {value:1, enumerable:true})['a']
|
|
1
|
|
|
|
js> // make sure defineProperty updates length properly for arrays
|
|
js> Object.defineProperty([], 0, {value:1}).length
|
|
1
|
|
|
|
js> // make sure that getters and setters are actually used to get and set property
|
|
js> Object.defineProperty({}, 'a', {get:function() { return "get called"; }}).a
|
|
get called
|
|
js> Object.defineProperty({}, 'a', {set:function(val) { print("set called with "+val); }}).a = 1; undefined;
|
|
set called with 1
|
|
|
|
js> // make sure defineProperty works for builtin properties
|
|
js> Object.defineProperty(JSON, 'stringify', {value:1}).stringify
|
|
1
|
|
js> Object.defineProperty(JSON, 'parse', {get:function() {print('do get'); return undefined}}).parse
|
|
do get
|
|
|
|
js> // an accessor property without a setter behaves as if the setter were undefined
|
|
js> // and thus the setter can be set to undefined even when configurable is false
|
|
js> var obj = Object.defineProperty({}, 'a', {get:function(){return 1}})
|
|
js> var _ = Object.defineProperty(obj, 'a', {set:undefined})
|
|
js>
|
|
|