Problem
I am looking for a way to reduce the minified (by the Closure Compiler with ADVANCED_OPTIMIZATIONS) size of my code. To do this, I am looking for a way to apply a function to each member of a destruction assignment. Browser compatibility is not a concern just so long as Closure understands it. The following is a condensed snippet from my current working code.
(function(window){
"use strict";
const {"Function": Function, "Array": Array} = window;
// bindInToBindable(Method)(Instance)(...) = Method.call(Instance, ...)
const bindInToBindable = Function["prototype"]["bind"]["bind"](Function["prototype"]["bind"]);
// bindInToCallable(Method)(Instance, ...) = Method.call(Instance, ...)
const bindInToCallable=bindInToBindable(Function["prototype"]["bind"],Function["prototype"]["call"]);
const ArrayPrototype = Array["prototype"];
const CALL_ARRAY_PROTOTYPE_POP =bindInToCallable(ArrayPrototype["POP"])
const CALL_ARRAY_PROTOTYPE_PUSH =bindInToCallable(ArrayPrototype["PUSH"]);
const CALL_ARRAY_PROTOTYPE_SHIFT =bindInToCallable(ArrayPrototype["SHIFT"])
const CALL_ARRAY_PROTOTYPE_UNSHIFT=bindInToCallable(ArrayPrototype["UNSHIFT"]);
// The rest of my code...
})(typeof global==="undefined" ? self : global);
Below is a persuado-code representation of what I am aiming for and have tried so far.
(function(window){
"use strict";
const {"Function": Function, "Array": Array} = window;
// bindInToBindable(Method)(Instance)(...) = Method.call(Instance, ...)
const bindInToBindable = Function["prototype"]["bind"]["bind"](Function["prototype"]["bind"]);
// bindInToCallable(Method)(Instance, ...) = Method.call(Instance, ...)
const bindInToCallable=bindInToBindable(Function["prototype"]["bind"],Function["prototype"]["call"]);
const bindInToCallable({
"pop": CALL_ARRAY_PROTOTYPE_POP,
"push": CALL_ARRAY_PROTOTYPE_PUSH,
"shift": CALL_ARRAY_PROTOTYPE_SHIFT,
"unshift": CALL_ARRAY_PROTOTYPE_UNSHIFT
}) = Array["prototype"];
// The rest of my code...
})(typeof global==="undefined" ? self : global);
So, is there a standards-compliant way to apply a function to each member of a destructing assignment? And/Or are there any alternatives that would make the code shorter?
P.S. The above code snippets are only a tiny portion of my real code. In my real code, there are hundreds of declarations, making this reduction in size quite practical.
Solution
You can try creating another function which binds the methods of a prototype all at once and returns an object with the bound methods which you can destructure:
const bindPrototype = prototype =>
Object.getOwnPropertyNames(prototype)
.filter(name => typeof prototype[name] === 'function' && name !== 'constructor') //Don't mess with constructors
.reduce((bound, currName) => {
bound[currName] = bindInToCallable(prototype[currName]);
return bound;
}, {});
This takes all the property names of the prototype, filters out the non-methods and constructors, then reduces the array of methods down into an object of all bound methods. Then, you can call it as and destructure/rebind:
const {
pop: CALL_ARRAY_PROTOTYPE_POP,
…
} = bindPrototype(Array.prototype);