What’s the use case?

Don’t forget that whenever you set a property, you only ever modify the first 
object in the prototype chain.

The “own property” debate mainly exists, because objects are (ab)used as 
dictionaries. Then you don’t want inherited entries such as "toString".


On Nov 8, 2011, at 8:59 , Felipe Gasper 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
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com



_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to