Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

157
Views
"prefix" function calls by specific function call

I have some JavaScript code consisting of several functions that may or may not call each other. Here is an example:

function a(x)    { return 2*x; }
function b(x, y) { return a(y) + x; }
function c()     { return b(1, 2); }

I have a special function that takes a function and its arguments and returns the computed value (among other things, see explanation below):

function pre(f, ...args) { return f(...args); }

Is it possible to "prefix" all function calls by this function WITHOUT needing to modify/reassign the functions?

I.e. the call pre(c); should behave as if the functions were defined like this:

function a(x) { return 2*x; }
function b(x, y) { return pre(a, y) + x; }
function c() { return pre(b, 1, 2); }
  • Maybe we can define an object that overrides "standard" function call behaviour, so that it intercepts the call and prefixes it with this function?
  • If this requires the presence of certain objects, or all functions to be member of a certain object, that is alright.
  • If this requires a function call to be written differently (not just c();), that is alright.

Use case:

I have a (Java) program in which an end-user can define JavaScript functions. This program reads some external data and calls these JavaScript functions on it. Finally, some result from these function calls will be given back to the end-user.

The user-defined functions are side-effect free (the program makes sure of that); they are pure calculation functions. Because of that, it suffices to call each function mostly once - they will always give the same output for identical input. So I wanted to implement a caching mechanism inside pre like e.g. this:

var cache = new Map();
function pre(f, ...args) {
    var array = new Array(args.length + 1);
    array[0] = f.name;
    for (var i = 0; i < args.length; i++) {
        array[i+1] = args[i];
    }
    var stringified = JSON.stringify(array);
    if (cache.has(stringified)) {
        return cache.get(stringified);
    }
    else {
        var calc = Object.freeze(f(...args));
        cache.set(stringified, calc);
        return calc;
    }
}

I currently implemented it so that I just modify all user-defined functions (which are given as strings, so I manipulate strings) to contain the pre call. But I'm interested in a more elegant solution - a solution that does not require code modification - and if there is, I'm sure the knowledge of that solution can help in many situations.

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

If I'm understanding you correctly, you want to be able to define functions like this:

function a(x)    { return 2*x; }
function b(x, y) { return a(y) + x; }
function c()     { return b(1, 2); }

and then after defining them (after the functions and the a, b, and c bindings for them exist), intercept all of the calls to a, b, or c (including the ones inside b and c) without reassigning the a, b, or c identifiers (more formally, bindings).

You can't do that. It would require reaching into b (for instance) and changing which a binding b uses to find and call the function assigned to a. You can change the value of the a binding that b uses (e.g., which function a refers to) by reassigning it, but not which a binding b uses.

Just for the sake of any lurkers who want to know how to do it with reassignment, here's how, but the OP has specifically said they don't want to do this:

var cache = new Map();
function pre(f, ...args) {
    var array = new Array(args.length + 1);
    array[0] = f.name;
    for (var i = 0; i < args.length; i++) {
        array[i+1] = args[i];
    }
    var stringified = JSON.stringify(array);
    if (cache.has(stringified)) {
        return cache.get(stringified);
    }
    else {
        var calc = Object.freeze(f(...args));
        cache.set(stringified, calc);
        return calc;
    }
}

// Doesn't handle `this` because the OP didn't need to and the
// `pre` function would have to be modified to handle it
function wrap(original) {
    return (...args) => pre(original, ...args);
}


function a(x) {
    console.log(`a called with`, x);
    return 2 * x;
}
function b(x, y) {
    console.log(`b called with`, x, y);
    return a(y) + x;
}
function c() {
    console.log(`c called`);
    return b(1, 2);
}

a = wrap(a);
b = wrap(b);
c = wrap(c);
console.log(`First call:`);
console.log(c());
console.log(`Second call:`);
console.log(c());


In a comment you've said:

More precisely, I want to know if there is a level between "what b(1, 2) does" (the function itself) and the ... thing ... (the interpreter?) that says "now call that function". And if there is a level in-between, I want to know if that can be modified.

The only level in-between in a standard JavaScript environment is the lexical environment object that holds the a, b, and c bindings, which is what we'd be changing by reassigning them. There's nothing else we can do to intercept/adjust those function calls.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!