I think you're overcomplicating all of this. There's no reason you need to store the tag on the object itself. If you create a separate object that uses the object's pointer as a key, not only will you conserve space, but you'll prevent any unintentional collisions should the arbitrary object happen to have a property named "_tagged".
var __tagged = {};
function tag(obj){
__tagged[obj] = true;
return obj;
}
function isTagged(obj){
return __tagged.hasOwnProperty(obj);
}
function getTagged(obj){
if(isTagged(obj)) return obj;
}
== EDIT ==
So I decided to take a minute to create a more robust tagging system. This is what I've created.
var tag = {
_tagged: {},
add: function(obj, tag){
var tags = this._tagged[obj] || (this._tagged[obj] = []);
if(tag) tags.push(tag);
return obj;
},
remove: function(obj, tag){
if(this.isTagged(obj)){
if(tag === undefined) delete this._tagged[obj];
else{
var idx = this._tagged[obj].indexOf(tag);
if(idx != -1) this._tagged[obj].splice(idx, 1);
}
}
},
isTagged: function(obj){
return this._tagged.hasOwnProperty(obj);
},
get: function(tag){
var objects = this._tagged
, list = []
;//var
for(var o in objects){
if(objects.hasOwnProperty(o)){
if(objects[o].indexOf(tag) != -1) list.push(o);
}
}
return list;
}
}
Not only can you tag an object, but you can actually specify different types of tags and retrieve objects with specific tags in the form of a list. Let me give you an example.
var a = 'foo'
, b = 'bar'
, c = 'baz'
;//var
tag.add(a);
tag.add(b, 'tag1');
tag.add(c, 'tag1');
tag.add(c, 'tag2');
tag.isTagged(a); // true
tag.isTagged(b); // true
tag.isTagged(c); // true
tag.remove(a);
tag.isTagged(a); // false
tag.get('tag1'); // [b, c]
tag.get('tag2'); // [c]
tag.get('blah'); // []
tag.remove(c, 'tag1');
tag.get('tag1'); // [b]