UNPKG

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