]> Lady’s Gitweb - Pisces/blobdiff - value.js
Add methods for own entries and values to object.js
[Pisces] / value.js
index 5e9f0524c9419291802716602f1080c518db1ad8..cf858ad2a32bfc1b5e7445aebc67e4ee8a0f1577 100644 (file)
--- a/value.js
+++ b/value.js
@@ -45,40 +45,220 @@ export const {
   unscopables: UNSCOPABLES,
 } = Symbol;
 
+export const {
+  /**
+   * ln(10).
+   *
+   * ※ This is an alias for `Math.LN10`.
+   */
+  LN10,
+
+  /**
+   * ln(2).
+   *
+   * ※ This is an alias for `Math.LN2`.
+   */
+  LN2,
+
+  /**
+   * log10(ℇ).
+   *
+   * ※ This is an alias for `Math.LOG10E`.
+   */
+  LOG10E: LOG10ℇ,
+
+  /**
+   * log2(ℇ).
+   *
+   * ※ This is an alias for `Math.LOG2E`.
+   */
+  LOG2E: LOG2ℇ,
+
+  /**
+   * sqrt(½).
+   *
+   * ※ This is an alias for `Math.SQRT1_2`.
+   */
+  SQRT1_2: RECIPROCAL_SQRT2,
+
+  /**
+   * sqrt(2).
+   *
+   * ※ This is an alias for `Math.SQRT2`.
+   */
+  SQRT2,
+
+  /**
+   * The mathematical constant π.
+   *
+   * ※ This is an alias for `Math.PI`.
+   */
+  PI: Π,
+
+  /**
+   * The Euler number.
+   *
+   * ※ This is an alias for `Math.E`.
+   */
+  E: ℇ,
+} = Math;
+
+export const {
+  /**
+   * The largest number value less than infinity.
+   *
+   * ※ This is an alias for `Number.MAX_VALUE`.
+   */
+  MAX_VALUE: MAXIMUM_NUMBER,
+
+  /**
+   * 2**53 - 1.
+   *
+   * ※ This is an alias for `Number.MAX_SAFE_INTEGER`.
+   */
+  MAX_SAFE_INTEGER: MAXIMUM_SAFE_INTEGRAL_NUMBER,
+
+  /**
+   * The smallest number value greater than negative infinity.
+   *
+   * ※ This is an alias for `Number.MIN_VALUE`.
+   */
+  MIN_VALUE: MINIMUM_NUMBER,
+
+  /**
+   * -(2**53 - 1).
+   *
+   * ※ This is an alias for `Number.MIN_SAFE_INTEGER`.
+   */
+  MIN_SAFE_INTEGER: MINIMUM_SAFE_INTEGRAL_NUMBER,
+
+  /**
+   * Negative infinity.
+   *
+   * ※ This is an alias for `Number.NEGATIVE_INFINITY`.
+   */
+  NEGATIVE_INFINITY,
+
+  /**
+   * Nan.
+   *
+   * ※ This is an alias for `Number.NaN`.
+   */
+  NaN: NAN,
+
+  /**
+   * Positive infinity.
+   *
+   * ※ This is an alias for `Number.POSITIVE_INFINITY`.
+   */
+  POSITIVE_INFINITY,
+
+  /**
+   * The difference between 1 and the smallest number greater than 1.
+   *
+   * ※ This is an alias for `Number.EPSILON`.
+   */
+  EPSILON: Ε,
+} = Number;
+
+/** Negative zero. */
+export const NEGATIVE_ZERO = -0;
+
 /** The null primitive. */
 export const NULL = null;
 
+/** Positive zero. */
+export const POSITIVE_ZERO = 0;
+
 /** The undefined primitive. */
 export const UNDEFINED = undefined;
 
 /**
- * Returns −0 if the provided argument is "-0"; returns a number
- * representing the index if the provided argument is a canonical
- * numeric index string; otherwise, returns undefined.
+ * Completes the provided property descriptor by setting missing values
+ * to their defaults.
  *
- * There is no clamping of the numeric index, but note that numbers
- * above 2^53 − 1 are not safe nor valid integer indices.
+ * ※ This method modifies the provided object and returns undefined.
  */
-export const canonicalNumericIndexString = ($) => {
-  if (typeof $ !== "string") {
-    return undefined;
-  } else if ($ === "-0") {
-    return -0;
+export const completePropertyDescriptor = (Desc) => {
+  if (Desc === UNDEFINED) {
+    throw new TypeError(
+      "Piscēs: Cannot complete undefined property descriptor.",
+    );
+  } else if (!("get" in Desc || "set" in Desc)) {
+    // This is a generic or data descriptor.
+    if (!("value" in Desc)) {
+      // `value` is not defined on this.
+      Desc.value = UNDEFINED;
+    } else {
+      // `value` is already defined on this.
+      /* do nothing */
+    }
+    if (!("writable" in Desc)) {
+      // `writable` is not defined on this.
+      Desc.writable = false;
+    } else {
+      // `writable` is already defined on this.
+      /* do nothing */
+    }
   } else {
-    const n = +$;
-    return $ === `${n}` ? n : undefined;
+    // This is not a generic or data descriptor.
+    if (!("get" in Desc)) {
+      // `get` is not defined on this.
+      Desc.get = UNDEFINED;
+    } else {
+      // `get` is already defined on this.
+      /* do nothing */
+    }
+    if (!("set" in Desc)) {
+      // `set` is not defined on this.
+      Desc.set = UNDEFINED;
+    } else {
+      // `set` is already defined on this.
+      /* do nothing */
+    }
+  }
+  if (!("enumerable" in Desc)) {
+    // `enumerable` is not defined on this.
+    Desc.enumerable = false;
+  } else {
+    // `enumerable` is already defined on this.
+    /* do nothing */
+  }
+  if (!("configurable" in Desc)) {
+    // `configurable` is not defined on this.
+    Desc.configurable = false;
+  } else {
+    // `configurable` is already defined on this.
+    /* do nothing */
   }
 };
 
+/** Gets whether the provided value is an accessor descrtiptor. */
+export const isAccessorDescriptor = (Desc) =>
+  Desc !== UNDEFINED && ("get" in Desc || "set" in Desc);
+
+/** Gets whether the provided value is a data descrtiptor. */
+export const isDataDescriptor = (Desc) =>
+  Desc !== UNDEFINED && ("value" in Desc || "writable" in Desc);
+
 /**
- * Returns the length of the provided arraylike value.
- *
- * This can produce larger lengths than can actually be stored in
- * arrays, because no such restrictions exist on arraylike methods.
- *
- * ☡ This function throws if the provided value is not arraylike.
+ * Gets whether the provided value is a fully‐populated property
+ * descriptor.
+ */
+export const isFullyPopulatedDescriptor = (Desc) =>
+  Desc !== UNDEFINED &&
+  ("value" in Desc && "writable" in Desc ||
+    "get" in Desc && "set" in Desc) &&
+  "enumerable" in Desc && "configurable" in Desc;
+
+/**
+ * Gets whether the provided value is a generic (not accessor or data)
+ * descrtiptor.
  */
-export const lengthOfArraylike = ({ length }) => toLength(length);
+export const isGenericDescriptor = (Desc) =>
+  Desc !== UNDEFINED &&
+  !("get" in Desc || "set" in Desc || "value" in Desc ||
+    "writable" in Desc);
 
 export const {
   /**
@@ -93,6 +273,12 @@ export const {
    */
   ordinaryToPrimitive,
 
+  /**
+   * Returns a string function name generated from the provided value
+   * and optional prefix.
+   */
+  toFunctionName,
+
   /**
    * Returns the provided value converted to a primitive, or throws if
    * no such conversion is possible.
@@ -106,6 +292,10 @@ export const {
   toPrimitive,
 } = (() => {
   const { apply: call } = Reflect;
+  const getSymbolDescription = Object.getOwnPropertyDescriptor(
+    Symbol.prototype,
+    "description",
+  ).get;
 
   return {
     ordinaryToPrimitive: (O, hint) => {
@@ -133,6 +323,21 @@ export const {
         "Piscēs: Unable to convert object to primitive",
       );
     },
+    toFunctionName: ($, prefix = UNDEFINED) => {
+      const key = toPrimitive($, "string");
+      const name = (() => {
+        if (typeof key === "symbol") {
+          // The provided value is a symbol; format its description.
+          const description = call(getSymbolDescription, key, []);
+          return description === UNDEFINED ? "" : `[${description}]`;
+        } else {
+          // The provided value not a symbol; convert it to a string
+          // property key.
+          return `${key}`;
+        }
+      })();
+      return prefix !== UNDEFINED ? `${prefix} ${name}` : name;
+    },
     toPrimitive: ($, preferredType = "default") => {
       const hint = `${preferredType}`;
       if (
@@ -145,8 +350,8 @@ export const {
         );
       } else if (type($) === "object") {
         // The provided value is an object.
-        const exoticToPrim = $[TO_PRIMITIVE] ?? undefined;
-        if (exoticToPrim !== undefined) {
+        const exoticToPrim = $[TO_PRIMITIVE] ?? UNDEFINED;
+        if (exoticToPrim !== UNDEFINED) {
           // The provided value has an exotic primitive conversion
           // method.
           if (typeof exoticToPrim !== "function") {
@@ -171,9 +376,6 @@ export const {
 })();
 
 export const {
-  /** Returns whether the provided value is an integer index string. */
-  isIntegerIndexString,
-
   /**
    * Returns whether the provided values are the same value.
    *
@@ -201,27 +403,9 @@ export const {
   toLength,
 } = (() => {
   const { floor, max, min } = Math;
-  const {
-    MAX_SAFE_INTEGER: MAXIMUM_SAFE_INTEGRAL_NUMBER,
-    isInteger: isIntegralNumber,
-    isNaN: isNan,
-  } = Number;
+  const { isNaN: isNan } = Number;
   const { is } = Object;
   return {
-    isIntegerIndexString: ($) => {
-      const value = canonicalNumericIndexString($);
-      if (value !== undefined && isIntegralNumber(value)) {
-        // The provided value is an integral canonical numeric index
-        // string.
-        return sameValue(value, 0) ||
-          value > 0 && value <= MAXIMUM_SAFE_INTEGRAL_NUMBER &&
-            value === toLength(value);
-      } else {
-        // The provided value is not an integral canonical numeric
-        // index string.
-        return false;
-      }
-    },
     sameValue: (a, b) => is(a, b),
     sameValueZero: ($1, $2) => {
       const type1 = type($1);
@@ -264,6 +448,15 @@ export const {
   };
 })();
 
+/**
+ * Returns the property key (symbol or string) corresponding to the
+ * provided value.
+ */
+export const toPropertyKey = ($) => {
+  const key = toPrimitive($, "string");
+  return typeof key === "symbol" ? key : `${key}`;
+};
+
 /**
  * Returns a lowercase string identifying the type of the provided
  * value.
This page took 0.027173 seconds and 4 git commands to generate.