123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- 'use strict';
- // ECMAScript 6 symbols shim
- var $ = require('./$')
- , global = require('./$.global')
- , has = require('./$.has')
- , DESCRIPTORS = require('./$.descriptors')
- , $export = require('./$.export')
- , redefine = require('./$.redefine')
- , $fails = require('./$.fails')
- , shared = require('./$.shared')
- , setToStringTag = require('./$.set-to-string-tag')
- , uid = require('./$.uid')
- , wks = require('./$.wks')
- , keyOf = require('./$.keyof')
- , $names = require('./$.get-names')
- , enumKeys = require('./$.enum-keys')
- , isArray = require('./$.is-array')
- , anObject = require('./$.an-object')
- , toIObject = require('./$.to-iobject')
- , createDesc = require('./$.property-desc')
- , getDesc = $.getDesc
- , setDesc = $.setDesc
- , _create = $.create
- , getNames = $names.get
- , $Symbol = global.Symbol
- , $JSON = global.JSON
- , _stringify = $JSON && $JSON.stringify
- , setter = false
- , HIDDEN = wks('_hidden')
- , isEnum = $.isEnum
- , SymbolRegistry = shared('symbol-registry')
- , AllSymbols = shared('symbols')
- , useNative = typeof $Symbol == 'function'
- , ObjectProto = Object.prototype;
- // fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
- var setSymbolDesc = DESCRIPTORS && $fails(function(){
- return _create(setDesc({}, 'a', {
- get: function(){ return setDesc(this, 'a', {value: 7}).a; }
- })).a != 7;
- }) ? function(it, key, D){
- var protoDesc = getDesc(ObjectProto, key);
- if(protoDesc)delete ObjectProto[key];
- setDesc(it, key, D);
- if(protoDesc && it !== ObjectProto)setDesc(ObjectProto, key, protoDesc);
- } : setDesc;
- var wrap = function(tag){
- var sym = AllSymbols[tag] = _create($Symbol.prototype);
- sym._k = tag;
- DESCRIPTORS && setter && setSymbolDesc(ObjectProto, tag, {
- configurable: true,
- set: function(value){
- if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false;
- setSymbolDesc(this, tag, createDesc(1, value));
- }
- });
- return sym;
- };
- var isSymbol = function(it){
- return typeof it == 'symbol';
- };
- var $defineProperty = function defineProperty(it, key, D){
- if(D && has(AllSymbols, key)){
- if(!D.enumerable){
- if(!has(it, HIDDEN))setDesc(it, HIDDEN, createDesc(1, {}));
- it[HIDDEN][key] = true;
- } else {
- if(has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false;
- D = _create(D, {enumerable: createDesc(0, false)});
- } return setSymbolDesc(it, key, D);
- } return setDesc(it, key, D);
- };
- var $defineProperties = function defineProperties(it, P){
- anObject(it);
- var keys = enumKeys(P = toIObject(P))
- , i = 0
- , l = keys.length
- , key;
- while(l > i)$defineProperty(it, key = keys[i++], P[key]);
- return it;
- };
- var $create = function create(it, P){
- return P === undefined ? _create(it) : $defineProperties(_create(it), P);
- };
- var $propertyIsEnumerable = function propertyIsEnumerable(key){
- var E = isEnum.call(this, key);
- return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key]
- ? E : true;
- };
- var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){
- var D = getDesc(it = toIObject(it), key);
- if(D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true;
- return D;
- };
- var $getOwnPropertyNames = function getOwnPropertyNames(it){
- var names = getNames(toIObject(it))
- , result = []
- , i = 0
- , key;
- while(names.length > i)if(!has(AllSymbols, key = names[i++]) && key != HIDDEN)result.push(key);
- return result;
- };
- var $getOwnPropertySymbols = function getOwnPropertySymbols(it){
- var names = getNames(toIObject(it))
- , result = []
- , i = 0
- , key;
- while(names.length > i)if(has(AllSymbols, key = names[i++]))result.push(AllSymbols[key]);
- return result;
- };
- var $stringify = function stringify(it){
- if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined
- var args = [it]
- , i = 1
- , $$ = arguments
- , replacer, $replacer;
- while($$.length > i)args.push($$[i++]);
- replacer = args[1];
- if(typeof replacer == 'function')$replacer = replacer;
- if($replacer || !isArray(replacer))replacer = function(key, value){
- if($replacer)value = $replacer.call(this, key, value);
- if(!isSymbol(value))return value;
- };
- args[1] = replacer;
- return _stringify.apply($JSON, args);
- };
- var buggyJSON = $fails(function(){
- var S = $Symbol();
- // MS Edge converts symbol values to JSON as {}
- // WebKit converts symbol values to JSON as null
- // V8 throws on boxed symbols
- return _stringify([S]) != '[null]' || _stringify({a: S}) != '{}' || _stringify(Object(S)) != '{}';
- });
- // 19.4.1.1 Symbol([description])
- if(!useNative){
- $Symbol = function Symbol(){
- if(isSymbol(this))throw TypeError('Symbol is not a constructor');
- return wrap(uid(arguments.length > 0 ? arguments[0] : undefined));
- };
- redefine($Symbol.prototype, 'toString', function toString(){
- return this._k;
- });
- isSymbol = function(it){
- return it instanceof $Symbol;
- };
- $.create = $create;
- $.isEnum = $propertyIsEnumerable;
- $.getDesc = $getOwnPropertyDescriptor;
- $.setDesc = $defineProperty;
- $.setDescs = $defineProperties;
- $.getNames = $names.get = $getOwnPropertyNames;
- $.getSymbols = $getOwnPropertySymbols;
- if(DESCRIPTORS && !require('./$.library')){
- redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);
- }
- }
- var symbolStatics = {
- // 19.4.2.1 Symbol.for(key)
- 'for': function(key){
- return has(SymbolRegistry, key += '')
- ? SymbolRegistry[key]
- : SymbolRegistry[key] = $Symbol(key);
- },
- // 19.4.2.5 Symbol.keyFor(sym)
- keyFor: function keyFor(key){
- return keyOf(SymbolRegistry, key);
- },
- useSetter: function(){ setter = true; },
- useSimple: function(){ setter = false; }
- };
- // 19.4.2.2 Symbol.hasInstance
- // 19.4.2.3 Symbol.isConcatSpreadable
- // 19.4.2.4 Symbol.iterator
- // 19.4.2.6 Symbol.match
- // 19.4.2.8 Symbol.replace
- // 19.4.2.9 Symbol.search
- // 19.4.2.10 Symbol.species
- // 19.4.2.11 Symbol.split
- // 19.4.2.12 Symbol.toPrimitive
- // 19.4.2.13 Symbol.toStringTag
- // 19.4.2.14 Symbol.unscopables
- $.each.call((
- 'hasInstance,isConcatSpreadable,iterator,match,replace,search,' +
- 'species,split,toPrimitive,toStringTag,unscopables'
- ).split(','), function(it){
- var sym = wks(it);
- symbolStatics[it] = useNative ? sym : wrap(sym);
- });
- setter = true;
- $export($export.G + $export.W, {Symbol: $Symbol});
- $export($export.S, 'Symbol', symbolStatics);
- $export($export.S + $export.F * !useNative, 'Object', {
- // 19.1.2.2 Object.create(O [, Properties])
- create: $create,
- // 19.1.2.4 Object.defineProperty(O, P, Attributes)
- defineProperty: $defineProperty,
- // 19.1.2.3 Object.defineProperties(O, Properties)
- defineProperties: $defineProperties,
- // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
- getOwnPropertyDescriptor: $getOwnPropertyDescriptor,
- // 19.1.2.7 Object.getOwnPropertyNames(O)
- getOwnPropertyNames: $getOwnPropertyNames,
- // 19.1.2.8 Object.getOwnPropertySymbols(O)
- getOwnPropertySymbols: $getOwnPropertySymbols
- });
- // 24.3.2 JSON.stringify(value [, replacer [, space]])
- $JSON && $export($export.S + $export.F * (!useNative || buggyJSON), 'JSON', {stringify: $stringify});
- // 19.4.3.5 Symbol.prototype[@@toStringTag]
- setToStringTag($Symbol, 'Symbol');
- // 20.2.1.9 Math[@@toStringTag]
- setToStringTag(Math, 'Math', true);
- // 24.3.3 JSON[@@toStringTag]
- setToStringTag(global.JSON, 'JSON', true);
|