Hide method from enumeration
I want to add a method to every object.
When I just set Object.prototype.somefunction = ...
, it will come up when somebody enumerates the object using the usual pattern:
for (i in o){
if (o.hasOwnProperty(i)){
// do something with object
}
}
I tried to set it higher up the prototype chain, but that is not possible (at least not possible in Chrome):
TypeError: Cannot set property 'blah' of undefined
Can I set some flag or something on the method so that it won't get enumerated, just like the native met开发者_开发问答hods won't? (Or at least make hasOwnProperty()
return false
.)
Update: Sorry, I didn't look at it properly. I am using the ExtJS Framework and the object I was looking at had been processed by Ext.apply() which does the following:
for(var p in c){
o[p] = c[p];
}
That's where the "own property" flag gets lost.
So I guess I have no chance (in ECMAScript < 5) to inject a method into all objects that behaves like a native one?
I'm not sure I understand correctly. hasOwnProperty
is needed exactly for this case, and enumerating an object via
for (i in o){
if (o.hasOwnProperty(i)){
// do something with object
}
}
should not include methods from Object.prototype
. Can you please make a working example where you see this behaviour?
I also do not understand what you mean by
I tried to set it higher up the prototype chain
as Object.prototype
is the root of the chain, so you cannot get any higher.
In short, the solution is doing exactly what you claim you have done. If this does not work, probably you have made a mistake or found a bug.
I'm not sure what you mean. If a method/property is attached to the prototype, hasOwnProperty
will return false. See this code:
function Con(){this.enumerableProp = true;};
Con.prototype.fun = function(){return 'that\'s funny'};
var fun = new Con;
alert(fun.hasOwnProperty('fun')); //=> false
alert(fun.hasOwnProperty('enumerableProp')); //=> true
So, what do you mean?
Make a base class and make all other classes extend it. Add the method to the base class.
ES5 has Object.getOwnPropertyNames()
for this:
Object.prototype.lolwat = 42;
var obj = {
'foo': 1,
'bar': 2
};
Object.getOwnPropertyNames(obj); // ['bar', 'foo']
To see where it is supported: http://kangax.github.com/es5-compat-table/
However, for-in
combined with a hasOwnProperty
check should work too.
You get that error because there is nothing higher up the prototype chain.
Of note also is that adding to Object's prototype is not really recommended unless absolutely necessary for some reason
Edit: actually, my original answer was incorrect - as the others have pointed out, your object should not have that as own property if it's in Object's prototype.
In any case, if you want to create a prototype chain (or more importantly, avoid changing Object's prototype), you'll want to create your own class:
function MyBaseClass(){
}
MyBaseClass.prototype = new Object();
MyBaseClass.prototype.someMethod = function() { /* your method */ };
var o = new MyBaseClass();
o.hasOwnProperty('someMethod') //should be false
精彩评论