polyfill.js 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. 'use strict';
  2. var implementation = require('./implementation');
  3. var lacksProperEnumerationOrder = function () {
  4. if (!Object.assign) {
  5. return false;
  6. }
  7. /*
  8. * v8, specifically in node 4.x, has a bug with incorrect property enumeration order
  9. * note: this does not detect the bug unless there's 20 characters
  10. */
  11. var str = 'abcdefghijklmnopqrst';
  12. var letters = str.split('');
  13. var map = {};
  14. for (var i = 0; i < letters.length; ++i) {
  15. map[letters[i]] = letters[i];
  16. }
  17. var obj = Object.assign({}, map);
  18. var actual = '';
  19. for (var k in obj) {
  20. actual += k;
  21. }
  22. return str !== actual;
  23. };
  24. var assignHasPendingExceptions = function () {
  25. if (!Object.assign || !Object.preventExtensions) {
  26. return false;
  27. }
  28. /*
  29. * Firefox 37 still has "pending exception" logic in its Object.assign implementation,
  30. * which is 72% slower than our shim, and Firefox 40's native implementation.
  31. */
  32. var thrower = Object.preventExtensions({ 1: 2 });
  33. try {
  34. Object.assign(thrower, 'xy');
  35. } catch (e) {
  36. return thrower[1] === 'y';
  37. }
  38. return false;
  39. };
  40. module.exports = function getPolyfill() {
  41. if (!Object.assign) {
  42. return implementation;
  43. }
  44. if (lacksProperEnumerationOrder()) {
  45. return implementation;
  46. }
  47. if (assignHasPendingExceptions()) {
  48. return implementation;
  49. }
  50. return Object.assign;
  51. };