Subj : Re: custom class definition question To : Chris Tchou From : Brendan Eich Date : Tue Jul 20 2004 09:00 am Chris Tchou wrote: > I'm a little confused on how the whole custom class thing works - Is this > correct? > > The JSPropertyOp members of JSClass seem to work even if I use an empty > function that returns JS_TRUE. If "seem to work" means "are called by the engine", then yes. If you wish to stub JSPropertyOp members so that no call overhead accrues, use JS_PropertyStub -- for the getProperty and setProperty hooks, this stub is magic, and the engine will avoid the stub-call. > The engine appears to be actually adding/deleting/getting/setting the > properties on the underlying native object, and then calling the > JSPropertyOp to perform any modifications to the value (or just acting as a > callback in the case of delete). You can prevent addition by reporting an error or throwing an exception and returning false from your addProperty implementation. JSClass.delProperty can also fail if you want it to, or it can return JSVAL_TRUE or JSVAL_FALSE via *vp to affect the result of the delete operator being applied to your custom-class's object. > The JSResolveOp seems to only be called whenever we are attempting to access > a member that hasn't been used yet. I assume this is useful if you want to > calculate something once, but after that you can just let JS store it > internally in the native object. > (Is there some other use for it?) It's useful for many such cases where being lazy wins over eagerly predefining or reflecting properties. > Is also appears to continue calling resolve on member access even if > getProperty returns a value. It only stops if resolve defines a value or > after a setProperty call. Is there a reason for this? Resolve is supposed to define the property, if you want it to do so. Once the property is defined in the object, resolve won't be called any longer, until the property is deleted. > Once resolve defines a value for the property, then calls to getProperty no > longer pass the tinyid defined when you initialized the class, but instead > pass the property name string. So resolve overrides the initial property > definitions. Rather, it seems that *your* implementation of resolve used the wrong JS_DefineProperty API. If you want to define a property with a tinyid, use JS_DefinePropertyWithTinyId. But almost always, when defining properties with tinyids, you don't want each object to have its own copy of the property shadowing the prototype property. That's wasteful of memory without any benefit. Tinyids exist for fast dispatching in shared class getters and setters, based on prototype properties that don't need to be shadowed (that in fact may want to have JSPROP_SHARED among their attributes, if they are not JSPROP_READONLY). So I have to ask why you are resolving properties that you predefine on the class prototype? > In JS_InitClass, does parent_proto point to an object you want to use for > the initial prototype of objects of that class? No, it is the prototype object of the class prototype. If NULL, the default (Object.prototype) will be used. > When I pass NULL, it seems to work, but constructs it's own object of the > class to use as a prototype. JS_InitClass *always* constructs a new class prototype for the class being initialized for the given |obj| parameter. /be .