UNPKG

12.8 kBJavaScriptView Raw
1'use strict';
2var $ = require('../internals/export');
3var global = require('../internals/global');
4var IS_PURE = require('../internals/is-pure');
5var DESCRIPTORS = require('../internals/descriptors');
6var NATIVE_SYMBOL = require('../internals/native-symbol');
7var fails = require('../internals/fails');
8var has = require('../internals/has');
9var isArray = require('../internals/is-array');
10var isObject = require('../internals/is-object');
11var anObject = require('../internals/an-object');
12var toObject = require('../internals/to-object');
13var toIndexedObject = require('../internals/to-indexed-object');
14var toPrimitive = require('../internals/to-primitive');
15var createPropertyDescriptor = require('../internals/create-property-descriptor');
16var nativeObjectCreate = require('../internals/object-create');
17var objectKeys = require('../internals/object-keys');
18var getOwnPropertyNamesModule = require('../internals/object-get-own-property-names');
19var getOwnPropertyNamesExternal = require('../internals/object-get-own-property-names-external');
20var getOwnPropertySymbolsModule = require('../internals/object-get-own-property-symbols');
21var getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor');
22var definePropertyModule = require('../internals/object-define-property');
23var propertyIsEnumerableModule = require('../internals/object-property-is-enumerable');
24var createNonEnumerableProperty = require('../internals/create-non-enumerable-property');
25var redefine = require('../internals/redefine');
26var shared = require('../internals/shared');
27var sharedKey = require('../internals/shared-key');
28var hiddenKeys = require('../internals/hidden-keys');
29var uid = require('../internals/uid');
30var wellKnownSymbol = require('../internals/well-known-symbol');
31var wrappedWellKnownSymbolModule = require('../internals/wrapped-well-known-symbol');
32var defineWellKnownSymbol = require('../internals/define-well-known-symbol');
33var setToStringTag = require('../internals/set-to-string-tag');
34var InternalStateModule = require('../internals/internal-state');
35var $forEach = require('../internals/array-iteration').forEach;
36
37var HIDDEN = sharedKey('hidden');
38var SYMBOL = 'Symbol';
39var PROTOTYPE = 'prototype';
40var TO_PRIMITIVE = wellKnownSymbol('toPrimitive');
41var setInternalState = InternalStateModule.set;
42var getInternalState = InternalStateModule.getterFor(SYMBOL);
43var ObjectPrototype = Object[PROTOTYPE];
44var $Symbol = global.Symbol;
45var JSON = global.JSON;
46var nativeJSONStringify = JSON && JSON.stringify;
47var nativeGetOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;
48var nativeDefineProperty = definePropertyModule.f;
49var nativeGetOwnPropertyNames = getOwnPropertyNamesExternal.f;
50var nativePropertyIsEnumerable = propertyIsEnumerableModule.f;
51var AllSymbols = shared('symbols');
52var ObjectPrototypeSymbols = shared('op-symbols');
53var StringToSymbolRegistry = shared('string-to-symbol-registry');
54var SymbolToStringRegistry = shared('symbol-to-string-registry');
55var WellKnownSymbolsStore = shared('wks');
56var QObject = global.QObject;
57// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
58var USE_SETTER = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;
59
60// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
61var setSymbolDescriptor = DESCRIPTORS && fails(function () {
62 return nativeObjectCreate(nativeDefineProperty({}, 'a', {
63 get: function () { return nativeDefineProperty(this, 'a', { value: 7 }).a; }
64 })).a != 7;
65}) ? function (O, P, Attributes) {
66 var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor(ObjectPrototype, P);
67 if (ObjectPrototypeDescriptor) delete ObjectPrototype[P];
68 nativeDefineProperty(O, P, Attributes);
69 if (ObjectPrototypeDescriptor && O !== ObjectPrototype) {
70 nativeDefineProperty(ObjectPrototype, P, ObjectPrototypeDescriptor);
71 }
72} : nativeDefineProperty;
73
74var wrap = function (tag, description) {
75 var symbol = AllSymbols[tag] = nativeObjectCreate($Symbol[PROTOTYPE]);
76 setInternalState(symbol, {
77 type: SYMBOL,
78 tag: tag,
79 description: description
80 });
81 if (!DESCRIPTORS) symbol.description = description;
82 return symbol;
83};
84
85var isSymbol = NATIVE_SYMBOL && typeof $Symbol.iterator == 'symbol' ? function (it) {
86 return typeof it == 'symbol';
87} : function (it) {
88 return Object(it) instanceof $Symbol;
89};
90
91var $defineProperty = function defineProperty(O, P, Attributes) {
92 if (O === ObjectPrototype) $defineProperty(ObjectPrototypeSymbols, P, Attributes);
93 anObject(O);
94 var key = toPrimitive(P, true);
95 anObject(Attributes);
96 if (has(AllSymbols, key)) {
97 if (!Attributes.enumerable) {
98 if (!has(O, HIDDEN)) nativeDefineProperty(O, HIDDEN, createPropertyDescriptor(1, {}));
99 O[HIDDEN][key] = true;
100 } else {
101 if (has(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false;
102 Attributes = nativeObjectCreate(Attributes, { enumerable: createPropertyDescriptor(0, false) });
103 } return setSymbolDescriptor(O, key, Attributes);
104 } return nativeDefineProperty(O, key, Attributes);
105};
106
107var $defineProperties = function defineProperties(O, Properties) {
108 anObject(O);
109 var properties = toIndexedObject(Properties);
110 var keys = objectKeys(properties).concat($getOwnPropertySymbols(properties));
111 $forEach(keys, function (key) {
112 if (!DESCRIPTORS || $propertyIsEnumerable.call(properties, key)) $defineProperty(O, key, properties[key]);
113 });
114 return O;
115};
116
117var $create = function create(O, Properties) {
118 return Properties === undefined ? nativeObjectCreate(O) : $defineProperties(nativeObjectCreate(O), Properties);
119};
120
121var $propertyIsEnumerable = function propertyIsEnumerable(V) {
122 var P = toPrimitive(V, true);
123 var enumerable = nativePropertyIsEnumerable.call(this, P);
124 if (this === ObjectPrototype && has(AllSymbols, P) && !has(ObjectPrototypeSymbols, P)) return false;
125 return enumerable || !has(this, P) || !has(AllSymbols, P) || has(this, HIDDEN) && this[HIDDEN][P] ? enumerable : true;
126};
127
128var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(O, P) {
129 var it = toIndexedObject(O);
130 var key = toPrimitive(P, true);
131 if (it === ObjectPrototype && has(AllSymbols, key) && !has(ObjectPrototypeSymbols, key)) return;
132 var descriptor = nativeGetOwnPropertyDescriptor(it, key);
133 if (descriptor && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key])) {
134 descriptor.enumerable = true;
135 }
136 return descriptor;
137};
138
139var $getOwnPropertyNames = function getOwnPropertyNames(O) {
140 var names = nativeGetOwnPropertyNames(toIndexedObject(O));
141 var result = [];
142 $forEach(names, function (key) {
143 if (!has(AllSymbols, key) && !has(hiddenKeys, key)) result.push(key);
144 });
145 return result;
146};
147
148var $getOwnPropertySymbols = function getOwnPropertySymbols(O) {
149 var IS_OBJECT_PROTOTYPE = O === ObjectPrototype;
150 var names = nativeGetOwnPropertyNames(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject(O));
151 var result = [];
152 $forEach(names, function (key) {
153 if (has(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || has(ObjectPrototype, key))) {
154 result.push(AllSymbols[key]);
155 }
156 });
157 return result;
158};
159
160// `Symbol` constructor
161// https://tc39.github.io/ecma262/#sec-symbol-constructor
162if (!NATIVE_SYMBOL) {
163 $Symbol = function Symbol() {
164 if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor');
165 var description = !arguments.length || arguments[0] === undefined ? undefined : String(arguments[0]);
166 var tag = uid(description);
167 var setter = function (value) {
168 if (this === ObjectPrototype) setter.call(ObjectPrototypeSymbols, value);
169 if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false;
170 setSymbolDescriptor(this, tag, createPropertyDescriptor(1, value));
171 };
172 if (DESCRIPTORS && USE_SETTER) setSymbolDescriptor(ObjectPrototype, tag, { configurable: true, set: setter });
173 return wrap(tag, description);
174 };
175
176 redefine($Symbol[PROTOTYPE], 'toString', function toString() {
177 return getInternalState(this).tag;
178 });
179
180 propertyIsEnumerableModule.f = $propertyIsEnumerable;
181 definePropertyModule.f = $defineProperty;
182 getOwnPropertyDescriptorModule.f = $getOwnPropertyDescriptor;
183 getOwnPropertyNamesModule.f = getOwnPropertyNamesExternal.f = $getOwnPropertyNames;
184 getOwnPropertySymbolsModule.f = $getOwnPropertySymbols;
185
186 if (DESCRIPTORS) {
187 // https://github.com/tc39/proposal-Symbol-description
188 nativeDefineProperty($Symbol[PROTOTYPE], 'description', {
189 configurable: true,
190 get: function description() {
191 return getInternalState(this).description;
192 }
193 });
194 if (!IS_PURE) {
195 redefine(ObjectPrototype, 'propertyIsEnumerable', $propertyIsEnumerable, { unsafe: true });
196 }
197 }
198
199 wrappedWellKnownSymbolModule.f = function (name) {
200 return wrap(wellKnownSymbol(name), name);
201 };
202}
203
204$({ global: true, wrap: true, forced: !NATIVE_SYMBOL, sham: !NATIVE_SYMBOL }, {
205 Symbol: $Symbol
206});
207
208$forEach(objectKeys(WellKnownSymbolsStore), function (name) {
209 defineWellKnownSymbol(name);
210});
211
212$({ target: SYMBOL, stat: true, forced: !NATIVE_SYMBOL }, {
213 // `Symbol.for` method
214 // https://tc39.github.io/ecma262/#sec-symbol.for
215 'for': function (key) {
216 var string = String(key);
217 if (has(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string];
218 var symbol = $Symbol(string);
219 StringToSymbolRegistry[string] = symbol;
220 SymbolToStringRegistry[symbol] = string;
221 return symbol;
222 },
223 // `Symbol.keyFor` method
224 // https://tc39.github.io/ecma262/#sec-symbol.keyfor
225 keyFor: function keyFor(sym) {
226 if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol');
227 if (has(SymbolToStringRegistry, sym)) return SymbolToStringRegistry[sym];
228 },
229 useSetter: function () { USE_SETTER = true; },
230 useSimple: function () { USE_SETTER = false; }
231});
232
233$({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL, sham: !DESCRIPTORS }, {
234 // `Object.create` method
235 // https://tc39.github.io/ecma262/#sec-object.create
236 create: $create,
237 // `Object.defineProperty` method
238 // https://tc39.github.io/ecma262/#sec-object.defineproperty
239 defineProperty: $defineProperty,
240 // `Object.defineProperties` method
241 // https://tc39.github.io/ecma262/#sec-object.defineproperties
242 defineProperties: $defineProperties,
243 // `Object.getOwnPropertyDescriptor` method
244 // https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptors
245 getOwnPropertyDescriptor: $getOwnPropertyDescriptor
246});
247
248$({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL }, {
249 // `Object.getOwnPropertyNames` method
250 // https://tc39.github.io/ecma262/#sec-object.getownpropertynames
251 getOwnPropertyNames: $getOwnPropertyNames,
252 // `Object.getOwnPropertySymbols` method
253 // https://tc39.github.io/ecma262/#sec-object.getownpropertysymbols
254 getOwnPropertySymbols: $getOwnPropertySymbols
255});
256
257// Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives
258// https://bugs.chromium.org/p/v8/issues/detail?id=3443
259$({ target: 'Object', stat: true, forced: fails(function () { getOwnPropertySymbolsModule.f(1); }) }, {
260 getOwnPropertySymbols: function getOwnPropertySymbols(it) {
261 return getOwnPropertySymbolsModule.f(toObject(it));
262 }
263});
264
265// `JSON.stringify` method behavior with symbols
266// https://tc39.github.io/ecma262/#sec-json.stringify
267JSON && $({ target: 'JSON', stat: true, forced: !NATIVE_SYMBOL || fails(function () {
268 var symbol = $Symbol();
269 // MS Edge converts symbol values to JSON as {}
270 return nativeJSONStringify([symbol]) != '[null]'
271 // WebKit converts symbol values to JSON as null
272 || nativeJSONStringify({ a: symbol }) != '{}'
273 // V8 throws on boxed symbols
274 || nativeJSONStringify(Object(symbol)) != '{}';
275}) }, {
276 stringify: function stringify(it) {
277 var args = [it];
278 var index = 1;
279 var replacer, $replacer;
280 while (arguments.length > index) args.push(arguments[index++]);
281 $replacer = replacer = args[1];
282 if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined
283 if (!isArray(replacer)) replacer = function (key, value) {
284 if (typeof $replacer == 'function') value = $replacer.call(this, key, value);
285 if (!isSymbol(value)) return value;
286 };
287 args[1] = replacer;
288 return nativeJSONStringify.apply(JSON, args);
289 }
290});
291
292// `Symbol.prototype[@@toPrimitive]` method
293// https://tc39.github.io/ecma262/#sec-symbol.prototype-@@toprimitive
294if (!$Symbol[PROTOTYPE][TO_PRIMITIVE]) {
295 createNonEnumerableProperty($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);
296}
297// `Symbol.prototype[@@toStringTag]` property
298// https://tc39.github.io/ecma262/#sec-symbol.prototype-@@tostringtag
299setToStringTag($Symbol, SYMBOL);
300
301hiddenKeys[HIDDEN] = true;