123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- // ES2015 Symbol polyfill for environments that do not (or partially) support it
- "use strict";
- var d = require("d")
- , validateSymbol = require("./validate-symbol")
- , NativeSymbol = require("ext/global-this").Symbol
- , generateName = require("./lib/private/generate-name")
- , setupStandardSymbols = require("./lib/private/setup/standard-symbols")
- , setupSymbolRegistry = require("./lib/private/setup/symbol-registry");
- var create = Object.create
- , defineProperties = Object.defineProperties
- , defineProperty = Object.defineProperty;
- var SymbolPolyfill, HiddenSymbol, isNativeSafe;
- if (typeof NativeSymbol === "function") {
- try {
- String(NativeSymbol());
- isNativeSafe = true;
- } catch (ignore) {}
- } else {
- NativeSymbol = null;
- }
- // Internal constructor (not one exposed) for creating Symbol instances.
- // This one is used to ensure that `someSymbol instanceof Symbol` always return false
- HiddenSymbol = function Symbol(description) {
- if (this instanceof HiddenSymbol) throw new TypeError("Symbol is not a constructor");
- return SymbolPolyfill(description);
- };
- // Exposed `Symbol` constructor
- // (returns instances of HiddenSymbol)
- module.exports = SymbolPolyfill = function Symbol(description) {
- var symbol;
- if (this instanceof Symbol) throw new TypeError("Symbol is not a constructor");
- if (isNativeSafe) return NativeSymbol(description);
- symbol = create(HiddenSymbol.prototype);
- description = description === undefined ? "" : String(description);
- return defineProperties(symbol, {
- __description__: d("", description),
- __name__: d("", generateName(description))
- });
- };
- setupStandardSymbols(SymbolPolyfill);
- setupSymbolRegistry(SymbolPolyfill);
- // Internal tweaks for real symbol producer
- defineProperties(HiddenSymbol.prototype, {
- constructor: d(SymbolPolyfill),
- toString: d("", function () { return this.__name__; })
- });
- // Proper implementation of methods exposed on Symbol.prototype
- // They won't be accessible on produced symbol instances as they derive from HiddenSymbol.prototype
- defineProperties(SymbolPolyfill.prototype, {
- toString: d(function () { return "Symbol (" + validateSymbol(this).__description__ + ")"; }),
- valueOf: d(function () { return validateSymbol(this); })
- });
- defineProperty(
- SymbolPolyfill.prototype,
- SymbolPolyfill.toPrimitive,
- d("", function () {
- var symbol = validateSymbol(this);
- if (typeof symbol === "symbol") return symbol;
- return symbol.toString();
- })
- );
- defineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toStringTag, d("c", "Symbol"));
- // Proper implementaton of toPrimitive and toStringTag for returned symbol instances
- defineProperty(
- HiddenSymbol.prototype, SymbolPolyfill.toStringTag,
- d("c", SymbolPolyfill.prototype[SymbolPolyfill.toStringTag])
- );
- // Note: It's important to define `toPrimitive` as last one, as some implementations
- // implement `toPrimitive` natively without implementing `toStringTag` (or other specified symbols)
- // And that may invoke error in definition flow:
- // See: https://github.com/medikoo/es6-symbol/issues/13#issuecomment-164146149
- defineProperty(
- HiddenSymbol.prototype, SymbolPolyfill.toPrimitive,
- d("c", SymbolPolyfill.prototype[SymbolPolyfill.toPrimitive])
- );
|