2

I'm sorry if this is a duplicate, but i really don't actually know how to even ask this question. I'm coming from a native language background where you have control of how parameters are pass (by value, reference or pointer), and even though i've been using javascript for many years, i still have a tough time with knowing when variables are being passed by reference or value sometimes.

I'm would like to allow a function to be overridden in a javascript class, but basically i'm having a problem passing the arguments as a reference to the function.

I'll have to provide an example because i don't know exactly how to explain this.

So i have a "class", i'll call it exampleClass:

exampleClass = function()
{
    var m_largearray = [];
    var m_width = 100;
    var m_funcParams = {data: m_largearray, width:m_width};
    var m_someFunction = function(_params){
        // do stuff
    }
    var m_finalValues = [];
    return {
        doProcessing: function()
        {
            // do some things
            m_finalValues = m_someFunction(m_funcParams);
            // do stuff with the m_finalValues
        }
        setFunction: function(_func, _params)
        {
            m_someFunction = _func;
            m_funcParams = _params;
        },
        largearray: m_largearray,
        width: m_width
    }
}

So this class has a function which gets called, doProcessing(). Inside this function, it calls another function that does part of the processing, but i would like to have control of this part of the processing outside the class when i do not want the default way to process the data.

So something like this:

var classinstance = exampleClass();
var somespecialarray = [];
var someint = 5;
var somewidth = 900;
classinstance.setFunction(function(_params){
    // do some processing with different set of params
    // even though somewidth was set to 400, i will still get _params.width = 900 here
    // return some array
},
{data:somespecialarray, anint:someint, width:somewidth});
somewidth = 400;
classinstance.doProcessing();

This is just a complete example of what i'm trying to do, i just wrote this code here off the top of my head so if theres errors thats why.

Anyway, the problem with this is that the parameter list i set (i've tried using an array instead of an object). When i set m_funcParams, it seems the data is copied rather than referenced. When i change these arguments, m_largearray for example, when the default function gets called, the parameter data is what it was when i originally set m_funcParams, and not what i have updated m_largearray to be, the same as when i override the function, if i change somewidth from 900 to 800, when i call the function, the width parameter i still 900.

I hope this makes sense, i just need some clarity on why the function is not getting the updated values, and if there is a better way of doing this.

So, why is the function not getting the changed values, and is there a better way of doing this?

EDIT: Here is a complete working example. I think i just realized when i set the variable to be something else, i'm basically losing a "pointer" to the value it was before. if i set an element in an array, it updates in the function, but if i set the whole array, it does not

<html>
<body>
<script>
var exampleClass = function()
{
    var m_largearray = [1,2,3];
    var m_width = 100;
    var m_funcParams = {data: m_largearray, width:m_width};
    var m_someFunction = function(_params){
        // do stuff
        alert(_params.data[0]);
    }
    var m_finalValues = [];
    return {
        doProcessing: function()
        {
            // do some things
            m_finalValues = m_someFunction(m_funcParams);
            // do stuff with the m_finalValues
        },
        setFunction: function(_func, _params)
        {
            m_someFunction = _func;
            m_funcParams = _params;
        },
        largearray: m_largearray,
        width: m_width
    }
}

var classinstance = exampleClass();
classinstance.largearray[0] = 3;
classinstance.doProcessing();

classinstance.largearray = [7,8,9];
classinstance.doProcessing();

var somespecialarray = [4,5,6];
var someint = 5;
var somewidth = 900;
classinstance.setFunction(function(_params){
    // do some processing with different set of params
    // even though somewidth was set to 400, i will still get _params.width = 900 here
    alert(_params.width);
    // return some array
},
{data:somespecialarray, anint:someint, width:somewidth});
somewidth = 400;
classinstance.doProcessing();
</script>
</body>
</html>
6
  • 2
    JavaScript is always pass-by-value. It gets confusing because when a value is an object, it's really a reference to the object. The term "pass-by-reference" however involves the word "reference" but with a precise meaning that's not the same as what we mean when we talk about JavaScript object references. Commented Mar 16, 2016 at 13:10
  • can you provide working sample? Commented Mar 16, 2016 at 13:10
  • alright give me a second and i'll change the code to be a working example. Commented Mar 16, 2016 at 13:11
  • 1
    There's a good Snook article on this with simple examples: JavaScript: Passing by Value or by Reference Commented Mar 16, 2016 at 13:26
  • @Pointy, so to be clear, when you pass an object, your basically passing a "pointer" to the object, which is still basically pass by reference though isn't it? I think i've figured this out though, when i "re" set a variable that i had passed as a parameter, i'm actually creating a new variable and reusing that name. I was hoping there was a way to just set the value of that variable without losing the link between what i had passed as a parameter and the variable i'm setting Commented Mar 16, 2016 at 13:30

1 Answer 1

2

I hope I understood correctly and that this helps.

First of all when you pass an object to a function it passes as a reference, so changing one of it's properties will change the referred object's property.

However, when you invoked classinstance.setFunction in your example, you passed an object with a property width which recieved the variable somewidth, which is not an object so it gets passed by value.

Finally, when you changed someWidth to 800 you only changed someWidth, because width was passed as a value.

Edit: In addition, when invoking classinstance.setFunction, you passed a function with param _param which is not part of that scope.

Sign up to request clarification or add additional context in comments.

6 Comments

This is basically the conclusion i just came to when i created a working example above, thanks
please check my addition edit, I think there's another problem with your code
i don't know what you mean by your edit in addition. its just a parameter list, not an argument.
setFunction takes two params - _func & _params. You can't use the second param in the first, they don't share the same scope
but to solve this issue, i've figured what needs to happen is the argument needs to be an object, and when you change a variable, you'll have to change the object's variables, not the actual object you originally passed in. is this correct?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.