polyfill.js 1.3 KB

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