Skip to content

Instantly share code, notes, and snippets.

@getify
Created May 13, 2013 14:20
Show Gist options
  • Save getify/5568643 to your computer and use it in GitHub Desktop.
Save getify/5568643 to your computer and use it in GitHub Desktop.
interesting gotcha with `[[Prototype]]` and owned vs delegated properties
function Parent(){}
Parent.prototype.something = 42;
var p = new Parent();
p.hasOwnProperty("something"); // false
p.something--; // apparently the same as `p.something = p.something - 1`
p.hasOwnProperty("something"); // true!!
@insin
Copy link

insin commented May 13, 2013

Seems like it is the same, as it does a GetValue and a PutValue with the lhs, it's just that the GetValue has to walk [[Prototype]] to find anything:

http://es5.github.io/#x11.3.1

I prefer to have objects own their own properties if they're explicitly intended to be mutable. It feels like you tried to do a bad thing but accidentally ended up doing a not-bad thing :)

If I didn't think that way, I'd probably be using 'something' in p instead, which gives you true for both checks.

@getify
Copy link
Author

getify commented May 13, 2013

@insin yeah, I'm sure it's "well defined" in the language. I wasn't saying it was a _bug_, just a bit of a surprising gotcha, because -- usually looks and feels like it's modifying a variable/property in place, and this may be the only place where that subtle detail results in different behavior.

@getify
Copy link
Author

getify commented May 13, 2013

@insin also, just to clarify, the hasOwnProperty("something") checks aren't the real point or intent, I was just illustrating how it implicitly creates the shadowed property and doesn't do it "in place" as I expected. This "gotcha" was basically that I was expecting to modify a "shared" property between several objects all linked to a parent, and it wasn't being shared, and then I discovered this is why.

@wpears
Copy link

wpears commented Jun 5, 2013

It's interesting particularly because the "cure" for ++ is often said to be +=1... which in this case still causes shadowing (and for the same reason).

Also to note would be that something like

    Parent.prototype.decrementSomething=function(){
        this.something--;
    }

will also fail in the same way, due to the dynamic this binding.

You'd need an explicit reference like

    Parent.prototype.decrementSomething=function(){
        Parent.prototype.something--;
    }

to banish these ills... Though eschewing prototype-shared mutable data is another way ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment