Consider the following:
var x = {};
Object.defineProperty(x, "foo", {get: function(){return 1}});
print(x.__lookupGetter__("foo"));
Per the current spec, this should print undefined. Per every implementation, this should print the get
property of the foo
property descriptor on x
(i.e., the function).
As far as I can tell, __lookupGetter__
(with __lookupSetter__
being a very slight variation on this with .get
replaced by .set
) should be:
Object.prototype.__lookupGetter__ = function(propertyName) {
var obj = this;
do {
var desc = Object.getOwnPropertyDescriptor(obj, propertyName);
if (desc !== undefined)
return desc.get;
} while((obj = Object.getPrototypeOf(obj)) !== null);
}
…where all the built-ins have their initial values (i.e., Object.prototype
, Object.getOwnPropertyDescriptor
, Object.getPrototypeOf
, and undefined
).
Now, to look at the define
variants:
Set the internal [[Enumerable]] property of obj’s prop property to true.
What if obj
doesn't have a prop
property? In a case like var x = {}; x.__defineGetter__("foo", function(){return 1});
there is no foo
property on x
, as where would it come from?
Whenever a property with the name of prop
is accessed on the obj
object, call function
with the this
binding set to obj
, and return the result.
What does this even mean? What should the following do:
var x = {};
x.__defineGetter__("foo", function(){return 1});
print(Object.getOwnPropertyDescriptor("foo"));
print(Object.getOwnPropertyDescriptor("foo").get);
Is this accessing the property? What on earth should the object that Object.getOwnPropertyDescriptor
look like? You've not created a property descriptor for foo
, you've just magically defined its behaviour!
As far as I can tell, the actual behaviour is the following (again, assuming all built-ins have their initial value, and the setter variant just being the set
property and not the get
property):
Object.prototype.__defineGetter__ = function(propertyName, func) {
if (typeof func !== "function")
throw TypeError("not a function");
Object.defineProperty(this, propertyName, {get: func, enumerable: true});
}
As it is now, it is pretty much totally undefined how these functions relate to the ES object model (just some handwaving about "whenever a property with name of prop
is accessed on the obj
object").