polyfill.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. 'use strict';
  2. var d = require('d')
  3. , validateSymbol = require('./validate-symbol')
  4. , create = Object.create, defineProperties = Object.defineProperties
  5. , defineProperty = Object.defineProperty, objPrototype = Object.prototype
  6. , Symbol, HiddenSymbol, globalSymbols = create(null);
  7. var generateName = (function () {
  8. var created = create(null);
  9. return function (desc) {
  10. var postfix = 0, name;
  11. while (created[desc + (postfix || '')]) ++postfix;
  12. desc += (postfix || '');
  13. created[desc] = true;
  14. name = '@@' + desc;
  15. defineProperty(objPrototype, name, d.gs(null, function (value) {
  16. defineProperty(this, name, d(value));
  17. }));
  18. return name;
  19. };
  20. }());
  21. HiddenSymbol = function Symbol(description) {
  22. if (this instanceof HiddenSymbol) throw new TypeError('TypeError: Symbol is not a constructor');
  23. return Symbol(description);
  24. };
  25. module.exports = Symbol = function Symbol(description) {
  26. var symbol;
  27. if (this instanceof Symbol) throw new TypeError('TypeError: Symbol is not a constructor');
  28. symbol = create(HiddenSymbol.prototype);
  29. description = (description === undefined ? '' : String(description));
  30. return defineProperties(symbol, {
  31. __description__: d('', description),
  32. __name__: d('', generateName(description))
  33. });
  34. };
  35. defineProperties(Symbol, {
  36. for: d(function (key) {
  37. if (globalSymbols[key]) return globalSymbols[key];
  38. return (globalSymbols[key] = Symbol(String(key)));
  39. }),
  40. keyFor: d(function (s) {
  41. var key;
  42. validateSymbol(s);
  43. for (key in globalSymbols) if (globalSymbols[key] === s) return key;
  44. }),
  45. hasInstance: d('', Symbol('hasInstance')),
  46. isConcatSpreadable: d('', Symbol('isConcatSpreadable')),
  47. iterator: d('', Symbol('iterator')),
  48. match: d('', Symbol('match')),
  49. replace: d('', Symbol('replace')),
  50. search: d('', Symbol('search')),
  51. species: d('', Symbol('species')),
  52. split: d('', Symbol('split')),
  53. toPrimitive: d('', Symbol('toPrimitive')),
  54. toStringTag: d('', Symbol('toStringTag')),
  55. unscopables: d('', Symbol('unscopables'))
  56. });
  57. defineProperties(HiddenSymbol.prototype, {
  58. constructor: d(Symbol),
  59. toString: d('', function () { return this.__name__; })
  60. });
  61. defineProperties(Symbol.prototype, {
  62. toString: d(function () { return 'Symbol (' + validateSymbol(this).__description__ + ')'; }),
  63. valueOf: d(function () { return validateSymbol(this); })
  64. });
  65. defineProperty(Symbol.prototype, Symbol.toPrimitive, d('',
  66. function () { return validateSymbol(this); }));
  67. defineProperty(Symbol.prototype, Symbol.toStringTag, d('c', 'Symbol'));
  68. defineProperty(HiddenSymbol.prototype, Symbol.toPrimitive,
  69. d('c', Symbol.prototype[Symbol.toPrimitive]));
  70. defineProperty(HiddenSymbol.prototype, Symbol.toStringTag,
  71. d('c', Symbol.prototype[Symbol.toStringTag]));