300 lines
12 KiB
JavaScript
300 lines
12 KiB
JavaScript
|
'use strict';
|
||
|
var $ = require('../internals/export');
|
||
|
var global = require('../internals/global');
|
||
|
var IS_PURE = require('../internals/is-pure');
|
||
|
var DESCRIPTORS = require('../internals/descriptors');
|
||
|
var NATIVE_SYMBOL = require('../internals/native-symbol');
|
||
|
var fails = require('../internals/fails');
|
||
|
var has = require('../internals/has');
|
||
|
var isArray = require('../internals/is-array');
|
||
|
var isObject = require('../internals/is-object');
|
||
|
var anObject = require('../internals/an-object');
|
||
|
var toObject = require('../internals/to-object');
|
||
|
var toIndexedObject = require('../internals/to-indexed-object');
|
||
|
var toPrimitive = require('../internals/to-primitive');
|
||
|
var createPropertyDescriptor = require('../internals/create-property-descriptor');
|
||
|
var nativeObjectCreate = require('../internals/object-create');
|
||
|
var objectKeys = require('../internals/object-keys');
|
||
|
var getOwnPropertyNamesModule = require('../internals/object-get-own-property-names');
|
||
|
var getOwnPropertyNamesExternal = require('../internals/object-get-own-property-names-external');
|
||
|
var getOwnPropertySymbolsModule = require('../internals/object-get-own-property-symbols');
|
||
|
var getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor');
|
||
|
var definePropertyModule = require('../internals/object-define-property');
|
||
|
var propertyIsEnumerableModule = require('../internals/object-property-is-enumerable');
|
||
|
var hide = require('../internals/hide');
|
||
|
var redefine = require('../internals/redefine');
|
||
|
var shared = require('../internals/shared');
|
||
|
var sharedKey = require('../internals/shared-key');
|
||
|
var hiddenKeys = require('../internals/hidden-keys');
|
||
|
var uid = require('../internals/uid');
|
||
|
var wellKnownSymbol = require('../internals/well-known-symbol');
|
||
|
var wrappedWellKnownSymbolModule = require('../internals/wrapped-well-known-symbol');
|
||
|
var defineWellKnownSymbol = require('../internals/define-well-known-symbol');
|
||
|
var setToStringTag = require('../internals/set-to-string-tag');
|
||
|
var InternalStateModule = require('../internals/internal-state');
|
||
|
var $forEach = require('../internals/array-iteration').forEach;
|
||
|
|
||
|
var HIDDEN = sharedKey('hidden');
|
||
|
var SYMBOL = 'Symbol';
|
||
|
var PROTOTYPE = 'prototype';
|
||
|
var TO_PRIMITIVE = wellKnownSymbol('toPrimitive');
|
||
|
var setInternalState = InternalStateModule.set;
|
||
|
var getInternalState = InternalStateModule.getterFor(SYMBOL);
|
||
|
var ObjectPrototype = Object[PROTOTYPE];
|
||
|
var $Symbol = global.Symbol;
|
||
|
var JSON = global.JSON;
|
||
|
var nativeJSONStringify = JSON && JSON.stringify;
|
||
|
var nativeGetOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;
|
||
|
var nativeDefineProperty = definePropertyModule.f;
|
||
|
var nativeGetOwnPropertyNames = getOwnPropertyNamesExternal.f;
|
||
|
var nativePropertyIsEnumerable = propertyIsEnumerableModule.f;
|
||
|
var AllSymbols = shared('symbols');
|
||
|
var ObjectPrototypeSymbols = shared('op-symbols');
|
||
|
var StringToSymbolRegistry = shared('string-to-symbol-registry');
|
||
|
var SymbolToStringRegistry = shared('symbol-to-string-registry');
|
||
|
var WellKnownSymbolsStore = shared('wks');
|
||
|
var QObject = global.QObject;
|
||
|
// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
|
||
|
var USE_SETTER = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;
|
||
|
|
||
|
// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
|
||
|
var setSymbolDescriptor = DESCRIPTORS && fails(function () {
|
||
|
return nativeObjectCreate(nativeDefineProperty({}, 'a', {
|
||
|
get: function () { return nativeDefineProperty(this, 'a', { value: 7 }).a; }
|
||
|
})).a != 7;
|
||
|
}) ? function (O, P, Attributes) {
|
||
|
var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor(ObjectPrototype, P);
|
||
|
if (ObjectPrototypeDescriptor) delete ObjectPrototype[P];
|
||
|
nativeDefineProperty(O, P, Attributes);
|
||
|
if (ObjectPrototypeDescriptor && O !== ObjectPrototype) {
|
||
|
nativeDefineProperty(ObjectPrototype, P, ObjectPrototypeDescriptor);
|
||
|
}
|
||
|
} : nativeDefineProperty;
|
||
|
|
||
|
var wrap = function (tag, description) {
|
||
|
var symbol = AllSymbols[tag] = nativeObjectCreate($Symbol[PROTOTYPE]);
|
||
|
setInternalState(symbol, {
|
||
|
type: SYMBOL,
|
||
|
tag: tag,
|
||
|
description: description
|
||
|
});
|
||
|
if (!DESCRIPTORS) symbol.description = description;
|
||
|
return symbol;
|
||
|
};
|
||
|
|
||
|
var isSymbol = NATIVE_SYMBOL && typeof $Symbol.iterator == 'symbol' ? function (it) {
|
||
|
return typeof it == 'symbol';
|
||
|
} : function (it) {
|
||
|
return Object(it) instanceof $Symbol;
|
||
|
};
|
||
|
|
||
|
var $defineProperty = function defineProperty(O, P, Attributes) {
|
||
|
if (O === ObjectPrototype) $defineProperty(ObjectPrototypeSymbols, P, Attributes);
|
||
|
anObject(O);
|
||
|
var key = toPrimitive(P, true);
|
||
|
anObject(Attributes);
|
||
|
if (has(AllSymbols, key)) {
|
||
|
if (!Attributes.enumerable) {
|
||
|
if (!has(O, HIDDEN)) nativeDefineProperty(O, HIDDEN, createPropertyDescriptor(1, {}));
|
||
|
O[HIDDEN][key] = true;
|
||
|
} else {
|
||
|
if (has(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false;
|
||
|
Attributes = nativeObjectCreate(Attributes, { enumerable: createPropertyDescriptor(0, false) });
|
||
|
} return setSymbolDescriptor(O, key, Attributes);
|
||
|
} return nativeDefineProperty(O, key, Attributes);
|
||
|
};
|
||
|
|
||
|
var $defineProperties = function defineProperties(O, Properties) {
|
||
|
anObject(O);
|
||
|
var properties = toIndexedObject(Properties);
|
||
|
var keys = objectKeys(properties).concat($getOwnPropertySymbols(properties));
|
||
|
$forEach(keys, function (key) {
|
||
|
if (!DESCRIPTORS || $propertyIsEnumerable.call(properties, key)) $defineProperty(O, key, properties[key]);
|
||
|
});
|
||
|
return O;
|
||
|
};
|
||
|
|
||
|
var $create = function create(O, Properties) {
|
||
|
return Properties === undefined ? nativeObjectCreate(O) : $defineProperties(nativeObjectCreate(O), Properties);
|
||
|
};
|
||
|
|
||
|
var $propertyIsEnumerable = function propertyIsEnumerable(V) {
|
||
|
var P = toPrimitive(V, true);
|
||
|
var enumerable = nativePropertyIsEnumerable.call(this, P);
|
||
|
if (this === ObjectPrototype && has(AllSymbols, P) && !has(ObjectPrototypeSymbols, P)) return false;
|
||
|
return enumerable || !has(this, P) || !has(AllSymbols, P) || has(this, HIDDEN) && this[HIDDEN][P] ? enumerable : true;
|
||
|
};
|
||
|
|
||
|
var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(O, P) {
|
||
|
var it = toIndexedObject(O);
|
||
|
var key = toPrimitive(P, true);
|
||
|
if (it === ObjectPrototype && has(AllSymbols, key) && !has(ObjectPrototypeSymbols, key)) return;
|
||
|
var descriptor = nativeGetOwnPropertyDescriptor(it, key);
|
||
|
if (descriptor && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key])) {
|
||
|
descriptor.enumerable = true;
|
||
|
}
|
||
|
return descriptor;
|
||
|
};
|
||
|
|
||
|
var $getOwnPropertyNames = function getOwnPropertyNames(O) {
|
||
|
var names = nativeGetOwnPropertyNames(toIndexedObject(O));
|
||
|
var result = [];
|
||
|
$forEach(names, function (key) {
|
||
|
if (!has(AllSymbols, key) && !has(hiddenKeys, key)) result.push(key);
|
||
|
});
|
||
|
return result;
|
||
|
};
|
||
|
|
||
|
var $getOwnPropertySymbols = function getOwnPropertySymbols(O) {
|
||
|
var IS_OBJECT_PROTOTYPE = O === ObjectPrototype;
|
||
|
var names = nativeGetOwnPropertyNames(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject(O));
|
||
|
var result = [];
|
||
|
$forEach(names, function (key) {
|
||
|
if (has(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || has(ObjectPrototype, key))) {
|
||
|
result.push(AllSymbols[key]);
|
||
|
}
|
||
|
});
|
||
|
return result;
|
||
|
};
|
||
|
|
||
|
// `Symbol` constructor
|
||
|
// https://tc39.github.io/ecma262/#sec-symbol-constructor
|
||
|
if (!NATIVE_SYMBOL) {
|
||
|
$Symbol = function Symbol() {
|
||
|
if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor');
|
||
|
var description = !arguments.length || arguments[0] === undefined ? undefined : String(arguments[0]);
|
||
|
var tag = uid(description);
|
||
|
var setter = function (value) {
|
||
|
if (this === ObjectPrototype) setter.call(ObjectPrototypeSymbols, value);
|
||
|
if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false;
|
||
|
setSymbolDescriptor(this, tag, createPropertyDescriptor(1, value));
|
||
|
};
|
||
|
if (DESCRIPTORS && USE_SETTER) setSymbolDescriptor(ObjectPrototype, tag, { configurable: true, set: setter });
|
||
|
return wrap(tag, description);
|
||
|
};
|
||
|
|
||
|
redefine($Symbol[PROTOTYPE], 'toString', function toString() {
|
||
|
return getInternalState(this).tag;
|
||
|
});
|
||
|
|
||
|
propertyIsEnumerableModule.f = $propertyIsEnumerable;
|
||
|
definePropertyModule.f = $defineProperty;
|
||
|
getOwnPropertyDescriptorModule.f = $getOwnPropertyDescriptor;
|
||
|
getOwnPropertyNamesModule.f = getOwnPropertyNamesExternal.f = $getOwnPropertyNames;
|
||
|
getOwnPropertySymbolsModule.f = $getOwnPropertySymbols;
|
||
|
|
||
|
if (DESCRIPTORS) {
|
||
|
// https://github.com/tc39/proposal-Symbol-description
|
||
|
nativeDefineProperty($Symbol[PROTOTYPE], 'description', {
|
||
|
configurable: true,
|
||
|
get: function description() {
|
||
|
return getInternalState(this).description;
|
||
|
}
|
||
|
});
|
||
|
if (!IS_PURE) {
|
||
|
redefine(ObjectPrototype, 'propertyIsEnumerable', $propertyIsEnumerable, { unsafe: true });
|
||
|
}
|
||
|
}
|
||
|
|
||
|
wrappedWellKnownSymbolModule.f = function (name) {
|
||
|
return wrap(wellKnownSymbol(name), name);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
$({ global: true, wrap: true, forced: !NATIVE_SYMBOL, sham: !NATIVE_SYMBOL }, {
|
||
|
Symbol: $Symbol
|
||
|
});
|
||
|
|
||
|
$forEach(objectKeys(WellKnownSymbolsStore), function (name) {
|
||
|
defineWellKnownSymbol(name);
|
||
|
});
|
||
|
|
||
|
$({ target: SYMBOL, stat: true, forced: !NATIVE_SYMBOL }, {
|
||
|
// `Symbol.for` method
|
||
|
// https://tc39.github.io/ecma262/#sec-symbol.for
|
||
|
'for': function (key) {
|
||
|
var string = String(key);
|
||
|
if (has(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string];
|
||
|
var symbol = $Symbol(string);
|
||
|
StringToSymbolRegistry[string] = symbol;
|
||
|
SymbolToStringRegistry[symbol] = string;
|
||
|
return symbol;
|
||
|
},
|
||
|
// `Symbol.keyFor` method
|
||
|
// https://tc39.github.io/ecma262/#sec-symbol.keyfor
|
||
|
keyFor: function keyFor(sym) {
|
||
|
if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol');
|
||
|
if (has(SymbolToStringRegistry, sym)) return SymbolToStringRegistry[sym];
|
||
|
},
|
||
|
useSetter: function () { USE_SETTER = true; },
|
||
|
useSimple: function () { USE_SETTER = false; }
|
||
|
});
|
||
|
|
||
|
$({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL, sham: !DESCRIPTORS }, {
|
||
|
// `Object.create` method
|
||
|
// https://tc39.github.io/ecma262/#sec-object.create
|
||
|
create: $create,
|
||
|
// `Object.defineProperty` method
|
||
|
// https://tc39.github.io/ecma262/#sec-object.defineproperty
|
||
|
defineProperty: $defineProperty,
|
||
|
// `Object.defineProperties` method
|
||
|
// https://tc39.github.io/ecma262/#sec-object.defineproperties
|
||
|
defineProperties: $defineProperties,
|
||
|
// `Object.getOwnPropertyDescriptor` method
|
||
|
// https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptors
|
||
|
getOwnPropertyDescriptor: $getOwnPropertyDescriptor
|
||
|
});
|
||
|
|
||
|
$({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL }, {
|
||
|
// `Object.getOwnPropertyNames` method
|
||
|
// https://tc39.github.io/ecma262/#sec-object.getownpropertynames
|
||
|
getOwnPropertyNames: $getOwnPropertyNames,
|
||
|
// `Object.getOwnPropertySymbols` method
|
||
|
// https://tc39.github.io/ecma262/#sec-object.getownpropertysymbols
|
||
|
getOwnPropertySymbols: $getOwnPropertySymbols
|
||
|
});
|
||
|
|
||
|
// Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives
|
||
|
// https://bugs.chromium.org/p/v8/issues/detail?id=3443
|
||
|
$({ target: 'Object', stat: true, forced: fails(function () { getOwnPropertySymbolsModule.f(1); }) }, {
|
||
|
getOwnPropertySymbols: function getOwnPropertySymbols(it) {
|
||
|
return getOwnPropertySymbolsModule.f(toObject(it));
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// `JSON.stringify` method behavior with symbols
|
||
|
// https://tc39.github.io/ecma262/#sec-json.stringify
|
||
|
JSON && $({ target: 'JSON', stat: true, forced: !NATIVE_SYMBOL || fails(function () {
|
||
|
var symbol = $Symbol();
|
||
|
// MS Edge converts symbol values to JSON as {}
|
||
|
return nativeJSONStringify([symbol]) != '[null]'
|
||
|
// WebKit converts symbol values to JSON as null
|
||
|
|| nativeJSONStringify({ a: symbol }) != '{}'
|
||
|
// V8 throws on boxed symbols
|
||
|
|| nativeJSONStringify(Object(symbol)) != '{}';
|
||
|
}) }, {
|
||
|
stringify: function stringify(it) {
|
||
|
var args = [it];
|
||
|
var index = 1;
|
||
|
var replacer, $replacer;
|
||
|
while (arguments.length > index) args.push(arguments[index++]);
|
||
|
$replacer = replacer = args[1];
|
||
|
if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined
|
||
|
if (!isArray(replacer)) replacer = function (key, value) {
|
||
|
if (typeof $replacer == 'function') value = $replacer.call(this, key, value);
|
||
|
if (!isSymbol(value)) return value;
|
||
|
};
|
||
|
args[1] = replacer;
|
||
|
return nativeJSONStringify.apply(JSON, args);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// `Symbol.prototype[@@toPrimitive]` method
|
||
|
// https://tc39.github.io/ecma262/#sec-symbol.prototype-@@toprimitive
|
||
|
if (!$Symbol[PROTOTYPE][TO_PRIMITIVE]) hide($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);
|
||
|
// `Symbol.prototype[@@toStringTag]` property
|
||
|
// https://tc39.github.io/ecma262/#sec-symbol.prototype-@@tostringtag
|
||
|
setToStringTag($Symbol, SYMBOL);
|
||
|
|
||
|
hiddenKeys[HIDDEN] = true;
|