Skip to content

Instantly share code, notes, and snippets.

@xavierm02
Created June 13, 2011 14:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save xavierm02/1022883 to your computer and use it in GitHub Desktop.
Save xavierm02/1022883 to your computer and use it in GitHub Desktop.
Polyfill for Object.getPrototypeOf -- It will work unless your constructor's prototype doesn't have a constructor property (which means you assigned another object as prototype and didn't give it a constructor property...)
if ( typeof Object.getPrototypeOf !== "function" ) {
( function ( ) {
function getPrototypeValue( o, p ) {
if ( o.hasOwnProperty( p ) ) {
var ownValue = o[ p ];
if ( delete o[ p ] ) {
var prototypeValue = o[ p ];
o[ p ] = ownValue;
return prototypeValue;
} else {
return o[ p ];
}
} else {
return o[ p ];
}
}
if ( typeof "".__proto__ === "object" ) {
Object.getPrototypeOf = function( object ) {
return getPrototypeValue( object, '__proto__' );
};
} else {
Object.getPrototypeOf = function( object ) {
getPrototypeValue( object, 'constructor' ).prototype;
};
}
}( ) );
}
@incompl
Copy link

incompl commented Oct 20, 2011

Sorry this doesn't seem to work in IE8 or less. Here is a code sample that demonstrates the problem:

if ( typeof Object.getPrototypeOf2 !== "function" ) {
( function ( ) {
function getPrototypeValue( o, p ) {
if ( o.hasOwnProperty( p ) ) {
var ownValue = o[ p ];
if ( delete o[ p ] ) {
var prototypeValue = o[ p ];
o[ p ] = ownValue;
return prototypeValue;
} else {
return o[ p ];
}
} else {
return o[ p ];
}
}
if ( typeof "".proto === "object" ) {
Object.getPrototypeOf2 = function( object ) {
return getPrototypeValue( object, 'proto' );
};
} else {
Object.getPrototypeOf2 = function( object ) {
getPrototypeValue( object, 'constructor' ).prototype;
};
}
}( ) );
}

function Parent() {}
var parent = new Parent();
function Child() {}
Child.prototype = parent;
var child = new Child();

// child inherits directly from parent. this makes sense.
console.log(Object.getPrototypeOf2(child) === parent); // false in ie 8 or less

@xavierm02
Copy link
Author

That's normal...
There is no "normal" way you can get the prototype of an object in ES 3.
There is proto but it isn't standard.
And there is getting obj.constructor.prototype.
In your case, you redefine the prototype and therefore, it doesn't have a constructor property anymore so it fails. And there is nothing I can do about it.

@xavierm02
Copy link
Author

function C(){}
C.prototype = {};
Object.getPrototypeOf( new C( ) ); // FAIL

function C(){}
C.prototype = {constructor: C};
Object.getPrototypeOf( new C( ) ); // OK

@incompl
Copy link

incompl commented Oct 20, 2011

Normal or not, it shows that your getPrototypeOf does not behave the same as the getPrototypeOf implemented in newer browsers. A polyfill needs to have the exact same behavior.

@xavierm02
Copy link
Author

I just used this to reference it in an email I sent to John Resig about his blog post: http://ejohn.org/blog/objectgetprototypeof/
I really don't care whether it does work or not since I never used getPrototypeOf and probably never will.

@xavierm02
Copy link
Author

Updated the name of this gist. Happy?

@xavierm02
Copy link
Author

And how the hell did you find that Gist? -.-

@incompl
Copy link

incompl commented Oct 20, 2011

This was a top Google result for "getProtoTypeOf polyfill". I think your updating the description will really help people who stumble across it, so thanks!

@robrobbins
Copy link

This is incorrect:

// child inherits directly from parent. this makes sense.
console.log(Object.getPrototypeOf2(child) === parent); // false in ie 8 or less

Child is the prototype of child, with Parent being the prototype of Child

@xavierm02
Copy link
Author

It needs the constructor property to work properly.

@robrobbins
Copy link

What makes this work consistently is to enforce it with an Object.create polyfill that adds proto to all newly created objects when called, that way your else never gets used, but I suppose I am digressing...

@xavierm02
Copy link
Author

When you say proto you mean proto ? Because there are some browser supproting proto and not Object.create. So it would create some weird bugs.
And if it is proto then you need to add an else if.

@robrobbins
Copy link

if you polyfill Object.create to add the proto then you won't hit the else above.

@xavierm02
Copy link
Author

You'd still need it to work on objects created with the new operator.

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