Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Polyfill for Object.getPrototypeOf
if (typeof Object.getPrototypeOf != "function")(function(){
Object.getPrototypeOf =
(typeof "".__proto__ == "object")
? function(object){
return getPrototypeValue(object, '__proto__');
}
: function(object){
return getPrototypeValue(object, 'constructor').prototype;
}
;
var hasOwnProperty = Object.prototype.hasOwnProperty;
function getPrototypeValue(object, propertyName){
try{
if (hasOwnProperty.call(object, propertyName)){
var ownValue = object[propertyName];
delete object[propertyName];
}
return object[propertyName];
}
catch(e){throw e}
finally{
object[propertyName] = ownValue;
}
}
}());
@incompl

Here is some code that demonstrates that this polyfill is incorrect for IE8 and lower:

if (typeof Object.getPrototypeOf2 != "function")(function(){

Object.getPrototypeOf2 =
    (typeof "".__proto__ == "object")
    ? function(object){
        return getPrototypeValue(object, '__proto__');
    }
    : function(object){
        return getPrototypeValue(object, 'constructor').prototype;
    }
;

var hasOwnProperty = Object.prototype.hasOwnProperty;

function getPrototypeValue(object, propertyName){
    try{
        if (hasOwnProperty.call(object, propertyName)){
            var ownValue = object[propertyName];
            delete object[propertyName];
        }
        return object[propertyName];
    }
    catch(e){throw e}
    finally{
        object[propertyName] = ownValue;
    }
}

}());

function Parent() {}
var parent = new Parent();
function Child() {}
Child.prototype = parent;
var child = new Child();
if (Object.getPrototypeOf2(child) != parent) {
alert('fail 1'); // fail in ie8 and lower
}
else {
alert('win 1');
}
if (Object.getPrototypeOf2(child) == Parent.prototype) {
alert('fail 2'); // fail in ie8 and lower
}
else {
alert('win 2');
}

@subtleGradient

Dang. Back to the drawing board I guess.

@erik-kallen

Even though it might not work for returning the actual prototype, the idea works fine for determining the constructor of the prototype (but beware of the bug that causes object[propertyName] to be assigned to undefined if the property did not exist):

function getPrototypeValue(object, propertyName){
    if (Object.prototype.hasOwnProperty.call(object, propertyName)){
        try{
            var ownValue = object[propertyName];
            delete object[propertyName];
            return object[propertyName];
        }
        finally{
            object[propertyName] = ownValue;
        }
    }
    return object[propertyName];
}

function getBaseType(type) {
    return getPrototypeValue(type.prototype, 'constructor');
}
function Parent() {}
function Child1() {}
Child1.prototype = new Parent();
function Child2() {}
Child2.prototype = new Parent();
Child2.prototype.constructor = Child2;
alert((getBaseType(Child1) === Parent) + ", " + (getBaseType(Child2) === Parent) + ", " + (getBaseType(Parent) === Object));
alert((Parent.prototype.constructor === Parent) + ", " + (Child1.prototype.constructor === Parent) + ", " + (Child2.prototype.constructor === Child2));
@huei90

How about this

if (typeof Object.getPrototypeOf === 'undefined') {
    Object.getPrototypeOf = function (obj) {
        var t = typeof obj;
        if (!obj || (t !== 'object' && t !== 'function')) {
            throw new TypeError('not and object');
        }
        return obj.__proto__;
    };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.