|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 "use strict"; |
|
6 |
|
7 module.metadata = { |
|
8 "stability": "unstable" |
|
9 }; |
|
10 |
|
11 const create = Object.create; |
|
12 const prototypeOf = Object.getPrototypeOf; |
|
13 |
|
14 /** |
|
15 * Returns a new namespace, function that may can be used to access an |
|
16 * namespaced object of the argument argument. Namespaced object are associated |
|
17 * with owner objects via weak references. Namespaced objects inherit from the |
|
18 * owners ancestor namespaced object. If owner's ancestor is `null` then |
|
19 * namespaced object inherits from given `prototype`. Namespaces can be used |
|
20 * to define internal APIs that can be shared via enclosing `namespace` |
|
21 * function. |
|
22 * @examples |
|
23 * const internals = ns(); |
|
24 * internals(object).secret = secret; |
|
25 */ |
|
26 function ns() { |
|
27 const map = new WeakMap(); |
|
28 return function namespace(target) { |
|
29 if (!target) // If `target` is not an object return `target` itself. |
|
30 return target; |
|
31 // If target has no namespaced object yet, create one that inherits from |
|
32 // the target prototype's namespaced object. |
|
33 if (!map.has(target)) |
|
34 map.set(target, create(namespace(prototypeOf(target) || null))); |
|
35 |
|
36 return map.get(target); |
|
37 }; |
|
38 }; |
|
39 |
|
40 // `Namespace` is a e4x function in the scope, so we export the function also as |
|
41 // `ns` as alias to avoid clashing. |
|
42 exports.ns = ns; |
|
43 exports.Namespace = ns; |