]> Lady’s Gitweb - Pisces/blob - function.js
Treat object function args more consistently
[Pisces] / function.js
1 // ♓🌟 Piscēs ∷ function.js
2 // ====================================================================
3 //
4 // Copyright © 2022 Lady [@ Lady’s Computer].
5 //
6 // This Source Code Form is subject to the terms of the Mozilla Public
7 // License, v. 2.0. If a copy of the MPL was not distributed with this
8 // file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
9
10 export const {
11 /**
12 * Creates a bound function from the provided function using the
13 * provided this value and arguments list.
14 *
15 * ☡ As with call and construct, the arguments must be passed as an
16 * array.
17 */
18 bind,
19
20 /**
21 * Returns a new function which calls the provided function with its
22 * first argument as the `this` value and the remaining arguments
23 * passed through.
24 *
25 * ※ This is effectively an alias for Function.prototype.call.bind.
26 */
27 makeCallable,
28 } = (() => {
29 // ☡ Because these functions are used to initialize module constants,
30 // they can’t depend on imports from elsewhere.
31 const {
32 bind: functionBind,
33 call: functionCall,
34 } = Function.prototype;
35 const callBind = Reflect.apply(functionBind, functionCall, [
36 functionBind,
37 ]);
38 const {
39 create: objectCreate,
40 defineProperty: defineOwnProperty,
41 getPrototypeOf: getPrototype,
42 } = Object;
43 const { iterator: iteratorSymbol } = Symbol;
44 const { [iteratorSymbol]: arrayIterator } = Array.prototype;
45 const {
46 next: arrayIteratorNext,
47 } = getPrototype([][iteratorSymbol]());
48 const argumentIterablePrototype = {
49 [iteratorSymbol]() {
50 return {
51 next: callBind(
52 arrayIteratorNext,
53 call(arrayIterator, this.args, []),
54 ),
55 };
56 },
57 };
58 return {
59 bind: ($, boundThis, boundArgs) =>
60 callBind(
61 $,
62 boundThis,
63 ...objectCreate(
64 argumentIterablePrototype,
65 { args: { value: boundArgs } },
66 ),
67 ),
68 makeCallable: ($) =>
69 defineOwnProperty(
70 callBind(functionCall, $),
71 "length",
72 { value: $.length + 1 },
73 ),
74 };
75 })();
76
77 /**
78 * Calls the provided function with the provided this value and
79 * arguments list.
80 *
81 * ☡ This is an alias for Reflect.apply—the arguments must be passed
82 * as an array.
83 */
84 export const call = Reflect.apply;
85
86 /**
87 * Constructs the provided function with the provided arguments list
88 * and new target.
89 *
90 * ☡ This is an alias for Reflect.construct—the arguments must be
91 * passed as an array.
92 */
93 export const construct = Reflect.construct;
94
95 /**
96 * Returns the provided value.
97 *
98 * ※ This function can be called as a constructor. When used in an
99 * `extends` clause and called via `super`, it will set the value of
100 * `this` to the provided value, enabling it to be extended with
101 * private class features.
102 */
103 export const identity = function ($) {
104 return $;
105 };
106
107 /** Returns whether the provided value is callable. */
108 export const isCallable = ($) => typeof $ === "function";
109
110 /** Returns whether the provided value is a constructor. */
111 export const isConstructor = ($) => {
112 // The provided value is an object.
113 try {
114 construct(
115 function () {},
116 [],
117 $,
118 ); // will throw if $ is not a constructor
119 return true;
120 } catch {
121 return false;
122 }
123 };
124
125 /**
126 * Returns whether the provided object inherits from the prototype of
127 * the provided function.
128 */
129 export const ordinaryHasInstance = makeCallable(
130 Function.prototype[Symbol.hasInstance],
131 );
This page took 0.215562 seconds and 5 git commands to generate.