using Private name objects for declarative property definition.
brendan at mozilla.com
Sat Jul 9 17:02:08 PDT 2011
On Jul 9, 2011, at 4:32 PM, Allen Wirfs-Brock wrote:
> On Jul 9, 2011, at 1:43 PM, Brendan Eich wrote:
>> Do we want users extending Array or Function? Same problem as applies to object. In Edition N+1 we then collide. I don't see a difference in kind here.
> No, but the example we are setting is that if you are hanging such predicates off of constructors they should be constructors related to what you are testing rather than Object.
Ok, so I will stop whining about Array.isArray.
> ... However, if that isn't your concern (and my perspective is that in most cases it shouldn't be) you might as well use a public trademark property on instances in which case a direct test for that property is probably all you need.
> However, I agree that best practice would be for such property to have no access side-effects, regardless of how they were are implemented.
I'm not sure which however wins. ;-)
We have Array.isArray, Proxy.isTrapping (soon to be Proxy.isProxy?), Function.prototype.isGenerator (could be Function.isGenerator -- note different signature, so don't want both -- Object.getPrototypeOf(Function) === Function.prototype). I think methods on built-ins are winning.
> In general yes. Let's say a new kind of Crazy DOM node interfaces defines that it has a isCrazyNode property and also has semantics that requires the use of a Proxy to natively implement it in JS. In that case isCrazyNode needs to be implemented via the Proxy.
> On the other hand, we don't want random objects to start exposing isProxy properties just because a Proxy was used to implement it. That would be unnecessarily exposing implementation details. I fall back o my standard test, can Proxies be used to implement ES Array instances. If such instances implemented via Proxies had a visible isProxy property they would not be a accurate implemented on the ES spec. for array instances.
Right, so Proxy.isProxy -- on the built-in namespace object (like a standard module binding), not on each proxy instance.
But if you want isCrazyNode intercession via a Proxy, as you state above. For an Array emulation via Proxy, you'd have to monkey-patch Array.isArray.
> My argument for self-identify objects rather than independent predicates is above.
A brand or trademark is quite different from some old truthy data property. One could use private name objects for branding, no forgeries possible.
> If you buy that self-identify is better, then the question becomes data property or instance methods. To me that comes down to, if someone is going to have to code if (typeof obj.isFoo == 'function' && obj.isFoo()) ... why not just say if (obj.isFoo)...
I agree with that style when detecting a method.
BTW, it leads to the obj.isFoo?() conditional call idea (along with ?.). We never reached consensus there.
> A major source of monkey patch in large Smalltalk applications was people adding isFoo ^false methods to Object so they could test arbitrary objects for Fooness. I'm assume that as people start building complex JS applications using rich inheritance based duck typed "class" libraries they are going to find the need to do the same sort of classification testing.
This was instance-side, right? Seems like it would work with class-side inheritance too.
> Data property testing is a way to accomplish this without the monkey patching.
You mean without all the stub ^false / return false methods polluting Object? That is true, but again I return to the precedent (however recent) we've set: Array.isArray. Class-side, not instance-side.
More information about the es-discuss