How do I pass a function by reference and then call it?

I’m making a character animation engine and I want to make this animation class that lets me specify a function to call and 2 sets of arguments and then it uses lerp() to transition overtime using setInterval() between the two arguments. I have to use a function to set the value of whatever variable Im tryin to change because apparently js doesn’t have pass by reference for primitives but whatever. I’m basically trying to make my own version of setInterval().
Put simply, how do I be like:

function callThis(func, args) {
  func(...args);
}

function setPos(_x, _y) {
  x = _x;
  y = _y;
}

callThis(setX, [0, 10]);

Func will be a function and args will be an array of arguments to be passed with whatever func is referencing.

see “method()”.

Use it with global variables :wink:

Actually JS functions, just like Java’s, are ALWAYS pass by value, regardless it’s a primitive or object datatype.

When we pass a variable as a single argument to a function, the current value stored in that variable is read, and then the invoked function’s receiving parameter is initialized w/ a copy of that read value.

B/c a function’s parameter can only receive a copy of the current value stored in a passed variable, reassigning another value to that local parameter won’t replace the value stored in the original passed variable.

Obviously if that value happens to be an object, mutating its properties via the local parameter will reflect on the original passed variable as long as that variable still stores that same object value.

3 Likes

Have you tried doing it the way you proposed? You didn’t provide much detail, but it seems like it should work.

1 Like

Omg what the heck, the sample code I provided DOES work (if you ignore that I typed setX instead of setPos oops)! So this leads me to believe that maybe my problem has more to do with variable scope. There is a lot of object shenanigans going on in this project so I’ll try to show the code that’s causing errors in a way that can show what’s going on clearly.

gram.GQAnim = function(nodes, func, args1, args2, spd = 20, ease = gram.GEase.InOutQuad) {
    let gqa = this;
    gqa.nodes = nodes;
    gqa.func = func;
    gqa.args1 = args1;
    gqa.args2 = args2;
    gqa.spd = spd;
    gqa.ease = ease;
    gqa.anim = new gram.GAnim(gqa.nodes, gqa.spd);

    gqa.anim.stopAnim();

    gqa.anim.onAnim = function() {
      let completeness = gqa.ease(this.frame/(this.dur - 1));
      let newArgs = [];

      for (i = 0; i < gqa.args1.length; i++) {
        newArgs.push(lerp(gqa.args1[i], gqa.args2[i], completeness));
      }

      gqa.func(...newArgs);
    }
  }

GAnim is a constructor for making animations using setInterval, and GQAnim, which is what this code snippit is from, is a constructor for making instances of GAnim that will change a specific property over time with a specific ease function, basically like CSS animations. When you call startAnim() on a GAnim instance, it will call setInterval() with the function onAnim() for however long I specified. The issue here is that when I make a new instance of GQAnim, and then call startAnim() on the GAnim object it created, I get an error on the line that starts with “let completeness = …” and the error says “gqa.ease is not a function.”

I feel like this is getting really complicated and hard to follow, should I just link to the source?

Okay here’s the relevant source code I copied over to the web editor.

https://editor.p5js.org/thesuperdaine/sketches/T_A-3ktJY

I didn’t see this immediately and you do have quite a bit of indirection and nesting going on there which makes it difficult, but I think you just need a lowercase i instead of capital on line 482 of the code in the link.

ease = gram.GEase.InOutQuad

should be

ease = gram.GEase.inOutQuad)
1 Like

oh my GOSH you are so right!!! That did fix it! I had a feeling that it would have been something like that. And yeah I intend to make this a self-contained library, which is why it’s like nest city up in there lmao, but thank you so much for noticing that!