-1

Basically I expect console.log to output 'yeah' but it doesn't. What can I do to make it output yeah without directly referencing it inside of usefulFunction?

App = {
    config: {
        updateThis: 'false'
    },
    init: function(){
        this.usefulFunction(this.config.updateThis);
        this.consoleIt();
    },
    usefulFunction: function(item){
        item = 'yeah';
        // swap the above line for the line below and it works as expected
        // this.config.updateThis = 'yeah';
    },
    consoleIt: function(){
        console.log(this.config.updateThis);
    }
}

App.init();
4
  • Where did you copy that from ? Did you satisfied all the libraries dependencies ? Commented Feb 19, 2013 at 21:44
  • What is the purpose of the code? Is this a "I am learning" type of question or a "I'm trying to do ____ using this code and I'm stuck" type of question? If the latter, what are you trying to do? Commented Feb 19, 2013 at 21:45
  • Edouard / BryanH: I'm working on a project, and I ran into this problem. I created this usecase specifically for stackoverflow... once I solve it, I'll implement it back into my project. Commented Feb 19, 2013 at 21:46
  • The idea is this: I want to never explicitly call the App object other than the definition and the initial call. Every other call should be relative (with this). I have a utility function (in this case, usefulFunction) and I want it to update options I set inside of config. Commented Feb 19, 2013 at 21:49

3 Answers 3

2

in usefulFunction, you are expecting the C++ style of pass by reference to affect the original reference to config.updateThis, however, when you call

 this.usefulFunction(this.config.updateThis);

You are creating a new reference to the 'false' string (to pass to usefulFunction), and you can't update the original reference in this.config from usefulFunction.

The only way to address this is to pass the name of the object to update. Again, there is no C++ pass by reference in JS. Working example

App = {
    config: {
        updateThis: 'false'
    },
    init: function(){
        this.usefulFunction(this.config, 'updateThis');
        this.consoleIt();
    },
    usefulFunction: function(object, prop){
        object[prop] = 'yeah';
    },
    consoleIt: function(){
        console.log(this.config.updateThis);
    }
}

The Problem Is NOT That Strings are immutable

ᚗ̸̢̛͝ claims that the problem is that strings are immutable; however, the problem is deeper than that. The fact that strings are immutable means you can't change the current reference (and therefore have all other references update), but even if they were mutable, you couldn't just set a separate reference and affect existing references

var a = {b:1};
function change(obj) {
    // This is assigning {c:2} to obj but not to a
    // obj and a both point to the same object, but 
    // the following statement would simple make obj point to a different object
    // In other languages, you could define function(&obj) {}
    // That would allow the following statement to do what you intended
    obj = {c:2};
}

change(a);
console.log(a); // still {b:1}
Sign up to request clarification or add additional context in comments.

7 Comments

Oh... what you're saying is what the other guy is saying, you're just defining 'updateThis' in the init instead of directly specifying it inside of usefulFunction... ooooo
@EdouardLopez Please explain what you mean by accessible
@JuanMendes he probably means less accessible in the same sense that it took me a little bit more time to figure out what you were doing. It's really the same solution as above though, and you gave a much fuller explanation of what's going on, so you probably deserve to get the awarded answer.
though I am still sort of curious (because I might not know as much Javascript as I need to): so passing this.config.updateThis creates a new reference of this (I got that much from my commented line from my original code). But why doesn't this.config create a new instance of that object?
@JuanMendes great answer, great information. Thanks again (I wish I could award 2 answers).
|
2

You can pass an object (as opposed to a string object) to your function. The reason for this is because JavaScript strings are immutable.

Primitive values

All types except objects define immutable values. Specifically, strings are immutable (unlike in C for instance). We refer to values of these types as "primitive values." This is explained in more detail in the section on Strings below.

Source: https://developer.mozilla.org/en-US/docs/JavaScript/Data_structures


If you want to pass something mutable to your function, pass an object.

// Calling code
this.usefulFunction(this.config);

// Useful function isn't very useful
usefulFunction: function(config) {
   config.updateThis = "some new value";
}

Going back to your example, updating a config object via a function.

// Calling code
this.usefulFunction("updateThis", "some new value");

// Useful function is a bit useful
usefulFunction: function(name, value) {
    this.config[name] = value;
}

7 Comments

This is most likely going to be the answer... could you give me an example of what you described as well though (pass in the config item name)?
@ᚗ̸̢̛͝ could you provide references to your statement about object vs. string ?
@EdouardLopez Did you not see my comment above? My answer explains how to pass a string to affect the object so that the caller can decide which property will be affected.
@ᚗ̸̢̛͝ my code was intentionally vague. I didn't want to get caught up in the particulars of my code. I tried to demonstrate what I was trying to do in my production code as best as I could (e.g. be able to change updateThis). This is probably the simplest this could get. Though to be fair, I'm not sure exactly why this works and the way I'm doing it (which is admittedly very similar) are rendering different results. I'm guessing the truth lies in what you said in combination with what Juan said (but his solution seems a little bit more involved).
@EdouardLopez I'm aggressive? Did you not like my reason for the downvote? At least I don't hit and run, and I add an explanation so the person can improve their answer. If they improve it, I remove my downvote and maybe upvote it. By the way, someone agreed with me and upvoted my comment there. What does my downvoting have to do with the fact that my answer explains that you need to pass the name of the property as a string?
|
0

Assuming your code actually works:

App = {
    config: {
        updateThis: 'false'
    },
    init: function(){
        this.config.updateThis=this.usefulFunction( this.config.updateThis);
        this.consoleIt();
    },
    usefulFunction: function(item){
       return item = 'yeah';
        // swap the above line for the line below and it works as expected
        // this.config.updateThis = 'yeah';
    },
    consoleIt: function(){
        console.log(this.config.updateThis);
    }
}

2 Comments

-1 This doesn't explain anything about what the problem is. Also you're passing a variable to usefulFunction but never using it
As for explaining the problem,I thought , it was self explaining.. but guilty. As for passing the variable, it may have been used to decide the value returned or for some other purpose.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.