Last active
February 24, 2018 04:13
-
-
Save WebReflection/5593554 to your computer and use it in GitHub Desktop.
Object.setPrototypeOf(O, proto) full/complete polyfill with boolean flag for partial implementation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*jslint devel: true, indent: 2 */ | |
// 15.2.3.2 | |
if (!Object.setPrototypeOf) { | |
Object.setPrototypeOf = (function(Object, magic) { | |
'use strict'; | |
var set; | |
function checkArgs(O, proto) { | |
if (typeof O !== 'object' || O === null) { | |
throw new TypeError('can not set prototype on a non-object'); | |
} | |
if (typeof proto !== 'object' && proto !== null) { | |
throw new TypeError('can only set prototype to an object or null'); | |
} | |
} | |
function setPrototypeOf(O, proto) { | |
checkArgs(O, proto); | |
set.call(O, proto); | |
return O; | |
} | |
try { | |
// this works already in Firefox and Safari | |
set = Object.getOwnPropertyDescriptor(Object.prototype, magic).set; | |
set.call({}, null); | |
} catch (o_O) { | |
if ( | |
// IE < 11 cannot be shimmed | |
Object.prototype !== {}[magic] || | |
// neither can any browser that actually | |
// implemented __proto__ correctly | |
// (all but old V8 will return here) | |
{__proto__:null}.__proto__ === void 0 | |
// this case means null objects cannot be passed | |
// through setPrototypeOf in a reliable way | |
// which means here a **Sham** is needed instead | |
) { | |
return; | |
} | |
// nodejs 0.8 and 0.10 are (buggy and..) fine here | |
// probably Chrome or some old Mobile stock browser | |
set = function(proto) { | |
this[magic] = proto; | |
}; | |
// please note that this will **not** work | |
// in those browsers that do not inherit | |
// __proto__ by mistake from Object.prototype | |
// in these cases we should probably throw an error | |
// or at least be informed about the issue | |
setPrototypeOf.polyfill = setPrototypeOf( | |
setPrototypeOf({}, null), | |
Object.prototype | |
) instanceof Object; | |
// setPrototypeOf.polyfill === true means it works as meant | |
// setPrototypeOf.polyfill === false means it's not 100% reliable | |
// setPrototypeOf.polyfill === undefined | |
// or | |
// setPrototypeOf.polyfill == null means it's not a polyfill | |
// which means it works as expected | |
// we can even delete Object.prototype.__proto__; | |
} | |
return setPrototypeOf; | |
}(Object, '__proto__')); | |
} |
Thanks for your code!
Can you let me know which license is used for distribution of this code?
I'd like to use this code for a commercial app so I need to check the license.
Happy coding! :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This doesn't work on Opera 12 -- setPrototypeOf.polyfill = true, but
Object.setPrototypeOf(foo, null)
doesn't work.Hacky workaround in paulmillr/es6-shim#223