简体   繁体   中英

Can someone explain this small piece of javascript code to me?

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();

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}

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;
}

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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM