]> Lady’s Gitweb - Pisces/blobdiff - object.js
Add LazyLoader class
[Pisces] / object.js
index 578f84f5201f9d46907cc77ba36a30d1c984ddcb..a34423e7a5bbd1578154690f7f8d69767fb7e776 100644 (file)
--- a/object.js
+++ b/object.js
 import { bind, call } from "./function.js";
 import { toPrimitive, type } from "./value.js";
 
+/**
+ * An object whose properties are lazy‐loaded from the methods on the
+ * own properties of the provided object.
+ *
+ * This is useful when you are looking to reference properties on
+ * objects which, due to module dependency graphs, cannot be guaranteed
+ * to have been initialized yet.
+ *
+ * The resulting properties will have the same attributes (regarding
+ * configurability, enumerability, and writability) as the
+ * corresponding properties on the methods object. If a property is
+ * marked as writable, the method will never be called if it is set
+ * before it is gotten. By necessity, the resulting properties are all
+ * configurable before they are accessed for the first time.
+ *
+ * Methods will be called with the resulting object as their this
+ * value.
+ *
+ * LazyLoader objects have the same prototype as the passed methods
+ * object.
+ */
+export class LazyLoader extends null {
+  /** Constructs a new LazyLoader object. */
+  constructor(loadMethods) {
+    const result = objectCreate(getPrototype(loadMethods));
+    const methodKeys = getOwnPropertyKeys(loadMethods);
+    for (let index = 0; index < methodKeys.length; ++index) {
+      const methodKey = methodKeys[index];
+      const { configurable, enumerable, writable } =
+        getOwnPropertyDescriptor(loadMethods, methodKey);
+      defineOwnProperty(result, methodKey, {
+        configurable: true,
+        enumerable,
+        get: () => {
+          const value = call(loadMethods[methodKey], result, []);
+          defineOwnProperty(result, methodKey, {
+            configurable,
+            enumerable,
+            value,
+            writable,
+          });
+          return value;
+        },
+        set: writable
+          ? ($) =>
+            defineOwnProperty(result, methodKey, {
+              configurable,
+              enumerable,
+              value: $,
+              writable,
+            })
+          : void {},
+      });
+    }
+    return result;
+  }
+}
+
 /**
  * A property descriptor object.
  *
This page took 0.024018 seconds and 4 git commands to generate.