Closed
Bug 641257
Opened 14 years ago
Closed 14 years ago
Object.defineProperties doesn't work when the second argument is an Harmony proxy
Categories
(Core :: JavaScript Engine, defect)
Tracking
()
RESOLVED
INVALID
People
(Reporter: bruant.d, Unassigned)
Details
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:2.0) Gecko/20100101 Firefox/4.0
Build Identifier: FF4RC1
Test case:
----------------------------------
function handlerMaker(obj) {
return {
getOwnPropertyDescriptor: function(name) {
var desc = Object.getOwnPropertyDescriptor(obj, name);
if (desc !== undefined) { desc.configurable = true; }
return desc;
},
getPropertyDescriptor: function(name) {
return this.getOwnPropertyDescriptor(name); // incorrect !
},
getOwnPropertyNames: function() {
return Object.getOwnPropertyNames(obj);
},
getPropertyNames: function() {
return this.getOwnPropertyNames(); // incorrect !
},
defineProperty: function(name, desc) {
Object.defineProperty(obj, name, desc);
}
};
}
var target = {};
var props = Proxy.create(handlerMaker(target));
props['a'] = 'a';
var o = {};
Object.defineProperties(o, props);
console.log(o);
----------------------------------
If I had to guess, I'd say that this is related to defineProperties definition (http://es5.github.com/#x15.2.3.7). At step 3, "Let names be an internal list containing the names of each enumerable own property of props.". Note at the end of the algorithm: "If an implementation defines a specific order of enumeration for the for-in statement, that same enumeration order must be used to order the list elements in step 3 of this algorithm."
For proxies, this is supposed to be the 'keys' trap (which is supposed to be a derived trap).
Reproducible: Always
Steps to Reproduce:
1. Run test case
2.
3.
Actual Results:
Error message in Web console: "value is not a non-null object" at the line of the Object.defineProperties call
Expected Results:
o has same own enumerable properties than props (and target)
Reporter | ||
Comment 1•14 years ago
|
||
May be related to bug 609005?
Comment 2•14 years ago
|
||
This works fore me, when i return the expected stuff with getPropertyDescriptor.
{
value: {
value: 1
enumerable: true,
configurable: true,
writable: true
}
enumerable: true,
configurable: true,
writable: true
}
Minimal Example:
function handlerMaker(obj) {
return {
getPropertyDescriptor: function(name) {
print('getPropertyDescriptor: ' + name);
var desc = Object.getOwnPropertyDescriptor(obj, name);
desc.value = Object.getOwnPropertyDescriptor(obj, name);
return desc;
},
keys: function () {
print('keys');
return Object.keys(obj);
}
};
}
var props = Proxy.create(handlerMaker({a: 1}));
var o = {};
Object.defineProperties(o, props);
print(o.a);
Or did you wanted to show something else, related to enumeration?
Reporter | ||
Comment 3•14 years ago
|
||
Why would the return value of getPropertyDescriptor look like: {
value: {
value: 1
enumerable: true,
configurable: true,
writable: true
}
enumerable: true,
configurable: true,
writable: true
}
?
In ES5, a property descriptor (for data properties) looks like:
{value:true, enumerable:true, configurable:true, writable:true}
That's what you pass to Object.defineProperty and what is returned by Object.getOwnPropertyDescriptor.
On the WebConsole:
< Object.getOwnPropertyDescriptor(Array, 'prototype');
> ({value:[], writable:false, enumerable:false, configurable:false})
I assumed an bug in the enumeration, but the bug may be from what is expected as the getPropertyDescriptor output.
As explained here (http://wiki.ecmascript.org/doku.php?id=harmony:proxies), getOwnPropertyDescriptor and getPropertyDescriptor traps are both expected to return property descriptors, but nothing imposes the 'value' of this property descriptor to be itself a property descriptor.
Is there a reason why you said that this is expected?
Reporter | ||
Comment 4•14 years ago
|
||
Ok. So I was half wrong in my previous comment. Here is the fixed reduced test case:
----------------------
function handlerMaker(obj) {
return {
getPropertyDescriptor: function(name) {
print('getPropertyDescriptor: ' + name);
var desc = Object.getOwnPropertyDescriptor(obj, name);
return desc;
},
keys: function () {
print('keys');
return Object.keys(obj);
}
};
}
var props = Proxy.create(handlerMaker({a: {va1ue:1, enumerable:true}, b:{value:false, enumerable:true}}));
var o = {};
Object.defineProperties(o, props);
----------------------
However, for some reason, o.a in undefined (should be 1) and o.b is false (expected).
Reporter | ||
Comment 5•14 years ago
|
||
Filed Bug 641274
Reporter | ||
Comment 6•14 years ago
|
||
My mistake, there was no bug here with proxies or enumeration. Glad it helped catching another bug :-p
Status: UNCONFIRMED → RESOLVED
Closed: 14 years ago
Resolution: --- → INVALID
You need to log in
before you can comment on or make changes to this bug.
Description
•