jackxiao / jslibs

Automatically exported from code.google.com/p/jslibs
0 stars 0 forks source link

Enhance ObjEx to intercept instanceof and in calls #77

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
ObjEx has full support for interception of get/set/delete on itself (and
thus can pass on information from an auxObject or even be useful for
providing a native like interface to something like a hierarchical database
system.

However it does not do any handling of instanceof or in. You can't
intercept these, and they actually don't do anything even if you make ObjEx
intercept all get calls and return the data from the auxObject.

ie: If you create a ObjEx object, and make the get function return
auxObject[propertyName] from the aux object {foo: 'bar'} then you get;
o.constructor -> Object
o.foo -> bar
o instanceof Object -> false
o instanceof ObjEx -> false
'constructor' in o -> false
'foo' in o -> false

So, ObjEx has some issues yet some potential. Currently it doesn't do
anything with instanceof or in (in fact you don't even know if something is
an ObjEx instance).
This could be considered an issue, cause if you want to just use it to pass
on stuff from another object, spy on it or such, then all use of instanceof
or in won't return properly and it'll cause issues.

However, it does leave room for a bit of potential. Since no-one is
expecting `o instanceof ObjEx` to work we don't have to worry about
anything breaking for anyone if we go and decide to give the ability to
override in and instanceof's results.

There are quite a few uses for this. Firstly, one could use ObjEx to create
an interface to some sort of resource. For example, access to a semantic
database. One could set it up like `(new Subject('...')).propertyName)`
would return a new set of semantic data for what in SPARQL would be {
subject propertyName ?data }, and things like `in` could end up doing an
ask query to see if data is available.
Alternatively, ObjEx could easily be used to create a class system inside
of JavaScript. The whole way prototype based classes work is a bit of an
issue. You can't inherit getters correctly, and there are other subtle
caveats that aren't noticed right away. However, using ObjEx one could
create a special Class system that allows `static` properties as well as
chaining the inheritance of things from the prototype. An instanceof
override is missing for that though, without it one could never subclass
"Array" and have "ArraySubClassInstance instanceof Array" return true.

Just a small off suggestion. With this the number of possible overrides is
getting a little large. Perhaps ObjEx() should alternatively support an
Object as first input, something like:
var o = new ObjEx({
  get: ...,
  set: ...,
  add: ...,
  del: ...,
  __instanceof__: ..., /* or maybe */ 'instanceof': ...,
  __in__: ..., /* or maybe */ 'in': ...
}, auxObject});

Original issue reported on code.google.com by nadir.se...@gmail.com on 29 Nov 2008 at 5:37

GoogleCodeExporter commented 9 years ago
1/ instanceof do not work properly because ObjEx behaves like the Map object: 
it can
store any property names even __proto__, __parent__, toString, ...
This inhibit some default Object behaviors.

2/ 'foo' in obj check for the 'foo' property directly on obj.

I will try to understand how to hack a SpiderMonkey more deeply.

Original comment by sou...@gmail.com on 30 Nov 2008 at 3:22

GoogleCodeExporter commented 9 years ago
Note that in the previous post, /2 wrong because 'foo' property is check on the
current object *and* the prototype chain:
  var obj = { __proto__:{ a:1 } };
  'a' in obj; // is true
  obj.hasOwnProperty('a'); // is false

Original comment by sou...@gmail.com on 1 Mar 2009 at 9:35

GoogleCodeExporter commented 9 years ago
ObjEx will be replaced with the new Proxy engine class (see 
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Proxy)

Original comment by sou...@gmail.com on 2 Jun 2011 at 10:52