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