]> Lady’s Gitweb - Pisces/blobdiff - function.js
Add isArraylikeObject
[Pisces] / function.js
index 0b9ebcc5510a4caaa767622b60427d5d536d4e2e..46cab860fb27e655a44fba66d211b253758637da 100644 (file)
@@ -7,22 +7,71 @@
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
 
-import { defineOwnProperty, isObject } from "./object.js";
+export const {
+  /**
+   * Creates a bound function from the provided function using the
+   * provided this value and arguments list.
+   *
+   * ☡ As with call and construct, the arguments must be passed as an
+   * array.
+   */
+  bind,
 
-/**
- * Creates a bound function from the provided function using the
- * provided this value and arguments list.
- *
- * ☡ As with call and construct, the arguments must be passed as an
- * array.
- */
-export const bind = (() => {
-  const callBind = Function.prototype.call.bind(
-    Function.prototype.bind,
-  );
-  const bind = ($, boundThis, boundArgs) =>
-    callBind($, boundThis, ...boundArgs);
-  return bind;
+  /**
+   * Returns a new function which calls the provided function with its
+   * first argument as the `this` value and the remaining arguments
+   * passed through.
+   *
+   * ※ This is effectively an alias for Function.prototype.call.bind.
+   */
+  makeCallable,
+} = (() => {
+  // ☡ Because these functions are used to initialize module constants,
+  // they can’t depend on imports from elsewhere.
+  const {
+    bind: functionBind,
+    call: functionCall,
+  } = Function.prototype;
+  const callBind = Reflect.apply(functionBind, functionCall, [
+    functionBind,
+  ]);
+  const {
+    create: objectCreate,
+    defineProperty: defineOwnProperty,
+    getPrototypeOf: getPrototype,
+  } = Object;
+  const { iterator: iteratorSymbol } = Symbol;
+  const { [iteratorSymbol]: arrayIterator } = Array.prototype;
+  const {
+    next: arrayIteratorNext,
+  } = getPrototype([][iteratorSymbol]());
+  const argumentIterablePrototype = {
+    [iteratorSymbol]() {
+      return {
+        next: callBind(
+          arrayIteratorNext,
+          call(arrayIterator, this.args, []),
+        ),
+      };
+    },
+  };
+  return {
+    bind: ($, boundThis, boundArgs) =>
+      callBind(
+        $,
+        boundThis,
+        ...objectCreate(
+          argumentIterablePrototype,
+          { args: { value: boundArgs } },
+        ),
+      ),
+    makeCallable: ($) =>
+      defineOwnProperty(
+        callBind(functionCall, $),
+        "length",
+        { value: $.length + 1 },
+      ),
+  };
 })();
 
 /**
@@ -43,47 +92,40 @@ export const call = Reflect.apply;
  */
 export const construct = Reflect.construct;
 
+/**
+ * Returns the provided value.
+ *
+ * ※ This function can be called as a constructor. When used in an
+ * `extends` clause and called via `super`, it will set the value of
+ * `this` to the provided value, enabling it to be extended with
+ * private class features.
+ */
+export const identity = function ($) {
+  return $;
+};
+
+/** Returns whether the provided value is callable. */
+export const isCallable = ($) => typeof $ === "function";
+
 /** Returns whether the provided value is a constructor. */
 export const isConstructor = ($) => {
-  if (!isObject($)) {
-    // The provided value is not an object.
+  // The provided value is an object.
+  try {
+    construct(
+      function () {},
+      [],
+      $,
+    ); // will throw if $ is not a constructor
+    return true;
+  } catch {
     return false;
-  } else {
-    // The provided value is an object.
-    try {
-      construct(
-        function () {},
-        [],
-        $,
-      ); // will throw if $ is not a constructor
-      return true;
-    } catch {
-      return false;
-    }
   }
 };
 
-/**
- * Returns a new function which calls the provided function with its
- * first argument as the `this` value and the remaining arguments
- * passed through.
- *
- * ※ This is effectively an alias for Function.prototype.call.bind.
- */
-export const makeCallable = (() => {
-       const functionCall = Function.prototype.call;
-       const callable = ($) => defineOwnProperty(
-               bind(functionCall, $, []),
-               "length",
-               { value: $.length + 1 },
-       );
-       return callable;
-})();
-
 /**
  * Returns whether the provided object inherits from the prototype of
  * the provided function.
  */
 export const ordinaryHasInstance = makeCallable(
-       Function.prototype[Symbol.hasInstance],
+  Function.prototype[Symbol.hasInstance],
 );
This page took 0.027108 seconds and 4 git commands to generate.