UNPKG

2.84 kBJavaScriptView Raw
1'use strict';
2var $ = require('../internals/export');
3var uncurryThis = require('../internals/function-uncurry-this');
4var hiddenKeys = require('../internals/hidden-keys');
5var isObject = require('../internals/is-object');
6var hasOwn = require('../internals/has-own-property');
7var defineProperty = require('../internals/object-define-property').f;
8var getOwnPropertyNamesModule = require('../internals/object-get-own-property-names');
9var getOwnPropertyNamesExternalModule = require('../internals/object-get-own-property-names-external');
10var isExtensible = require('../internals/object-is-extensible');
11var uid = require('../internals/uid');
12var FREEZING = require('../internals/freezing');
13
14var REQUIRED = false;
15var METADATA = uid('meta');
16var id = 0;
17
18var setMetadata = function (it) {
19 defineProperty(it, METADATA, { value: {
20 objectID: 'O' + id++, // object ID
21 weakData: {} // weak collections IDs
22 } });
23};
24
25var fastKey = function (it, create) {
26 // return a primitive with prefix
27 if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
28 if (!hasOwn(it, METADATA)) {
29 // can't set metadata to uncaught frozen object
30 if (!isExtensible(it)) return 'F';
31 // not necessary to add metadata
32 if (!create) return 'E';
33 // add missing metadata
34 setMetadata(it);
35 // return object ID
36 } return it[METADATA].objectID;
37};
38
39var getWeakData = function (it, create) {
40 if (!hasOwn(it, METADATA)) {
41 // can't set metadata to uncaught frozen object
42 if (!isExtensible(it)) return true;
43 // not necessary to add metadata
44 if (!create) return false;
45 // add missing metadata
46 setMetadata(it);
47 // return the store of weak collections IDs
48 } return it[METADATA].weakData;
49};
50
51// add metadata on freeze-family methods calling
52var onFreeze = function (it) {
53 if (FREEZING && REQUIRED && isExtensible(it) && !hasOwn(it, METADATA)) setMetadata(it);
54 return it;
55};
56
57var enable = function () {
58 meta.enable = function () { /* empty */ };
59 REQUIRED = true;
60 var getOwnPropertyNames = getOwnPropertyNamesModule.f;
61 var splice = uncurryThis([].splice);
62 var test = {};
63 test[METADATA] = 1;
64
65 // prevent exposing of metadata key
66 if (getOwnPropertyNames(test).length) {
67 getOwnPropertyNamesModule.f = function (it) {
68 var result = getOwnPropertyNames(it);
69 for (var i = 0, length = result.length; i < length; i++) {
70 if (result[i] === METADATA) {
71 splice(result, i, 1);
72 break;
73 }
74 } return result;
75 };
76
77 $({ target: 'Object', stat: true, forced: true }, {
78 getOwnPropertyNames: getOwnPropertyNamesExternalModule.f
79 });
80 }
81};
82
83var meta = module.exports = {
84 enable: enable,
85 fastKey: fastKey,
86 getWeakData: getWeakData,
87 onFreeze: onFreeze
88};
89
90hiddenKeys[METADATA] = true;