1 | /**
|
2 | * @name objectProperty
|
3 | * @summary Assign a get property on the input object
|
4 | */
|
5 | export function objectProperty(that, key, getter, getName, index = 0) {
|
6 | const name = getName
|
7 | ? getName(key, index)
|
8 | : key;
|
9 | // There are 3 approaches here -
|
10 | // - Object.prototype.hasOwnProperty.call(that, key) - this only checks the current class, i.e
|
11 | // will retuirn false if the property is set in the parent class
|
12 | // - isUndefined(...) - this may yield a false positive when the property is there, but not set.
|
13 | // Additionally, on pre-defined getters it may make a call
|
14 | // - key in that - Does not need to be combined with either of the above and checks the full chain
|
15 | if (!(name in that)) {
|
16 | Object.defineProperty(that, name, {
|
17 | enumerable: true,
|
18 | // Unlike in lazy, we always call into the upper function, i.e. this method
|
19 | // does not cache old values (it is expected to be used for dynamic values)
|
20 | get: function () {
|
21 | return getter(key, index, this);
|
22 | }
|
23 | });
|
24 | }
|
25 | }
|
26 | /**
|
27 | * @name objectProperties
|
28 | * @summary Assign get properties on the input object
|
29 | */
|
30 | export function objectProperties(that, keys, getter, getName) {
|
31 | for (let i = 0, count = keys.length; i < count; i++) {
|
32 | objectProperty(that, keys[i], getter, getName, i);
|
33 | }
|
34 | }
|