Whats wrong with enumeration over own properties? Object.keys() gets all enumerable own properties in a for .. in loop.
for .. in gets all enumerable properties in prototype chains. I personally think it's bad practice to have code that enumerates over properties in the prototype chain. I can't see any good use case for it On Tue, Nov 8, 2011 at 7:59 AM, Felipe Gasper <[email protected]>wrote: > Hi everyone, > > There is a widespread practice of doing this: > > --------- > for (key in obj) { > if (obj.hasOwnProperty(key)) { … } > } > --------- > > The oft-stated purpose for this pattern is to weed out code that comes > from Object.prototype. The result, though, is that we prevent iteration > through *any* inherited properties, which seems like overkill for handling > the original problem. > > (Incidentally, I’m surprised that augmenting Object.prototype isn’t > warned/deprecated in ES5 Strict. It seems far easier to get people to stop > augmenting Obj.pro, which is likely to break all kinds of things, than to > get everyone to filter every for..in loop. But, anyway.) > > It’s especially unproductive because it works against prototypal > inheritance patterns. e.g.: > --------- > var dog = { speak: function() { return "arf!" } }; > var beagle = Object.create(dog); > beagle.colors = ["white","black","brown"]; > var my_dog = Object.create(beagle); > my_dog.name = "Chip"; > --------- > Note that filtering via hasOwnProperty() will prevent a for..in iteration > from seeing either "colors" or "speak". > > Another example: in YUI, it’s impossible to do this > would-otherwise-be-useful pattern: > --------- > var base_config = { width: "600px" }; > … > var my_config = Object.create(base_config); > my_config.visible = false; > var widget = new Y.Widget(my_config); > --------- > In the example above, YUI will not see the “width” property because YUI > rejects all inherited properties when it iterates through the configuration > hash. > > > > So, a solution I am considering for my own work defines two methods: > Object.gave(giver, key, obj) > Function.prototype.gave(key,**obj) > > They do what they look like: Object.gave checks if the “giver” really > “gave” the “key”ed value to the “obj”ect. The Function.prototype version > does the same but assigns the function’s prototype as “giver”. (The > original Object.gave() offloads to the prototype method if called with just > two args.) > > Thus: > ------------------ > var HOP = Object.prototype.**hasOwnProperty.call.bind(**Object.prototype.* > *hasOwnProperty); > Object.gave = function(giver,key,obj) { > if (arguments.length === 2) { > Function.prototype.gave.apply(**this,arguments); > } > > var last_prototype; > while ( obj !== giver ) { > if (HOP(obj,key) || (obj === last_prototype)) return false; > last_prototype = obj; > obj = Object.getPrototypeOf(obj); > } > > return true; > }; > > Function.prototype.gave = function(key,obj) { > return Object.gave( this.prototype, key, obj ); > }; > ------------------ > > Then, we can do: > -------------- > for (var key in obj) { > if (Object.gave(key,obj)) { … } > } > -------------- > > …which will still filter out anything in Object.prototype, but will allow > iteration through inherited properties. > > This seems to me far more useful in general than the hasOwnProperty() > check. > > Thoughts? > > -Felipe Gasper > cPanel, Inc. > ______________________________**_________________ > es-discuss mailing list > [email protected] > https://mail.mozilla.org/**listinfo/es-discuss<https://mail.mozilla.org/listinfo/es-discuss> >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

