简体   繁体   中英

Javascript: How can I create a function that 1. accepts a global variable as a parameter 2. alters the value of that global variable?

I'm trying to create a function that accepts a global variable as a parameter and changes the value of that global variable. Here's a simple example that illustrates what I'm trying to do:

var number = 20;
function setnew(num) {
  num += 1;
};

setnew(number);
console.log(number) //-> 20
                    //I want this to return 21

Even after the setnew function is invoked, number remains unchanged. Can someone explain why number remains unchanged and suggest another way to achieve my intended goal?

Since Javascript does not support true reference passing where you can change the original variable, you can't directly do what you're asking. The usual work-around is to wrap the global in an object.

var myGlobal = {
     counter: 0;
};

function increment(obj, prop) {
  ++obj[prop];
}

increment(myGlobal, "counter");
increment(myGlobal, "counter");

console.log(myGlobal.counter);   // 2

Or, if the property name is already known, you can just do this:

var myGlobal = {
     counter: 0;
};

function incrementCnt(obj) {
  ++obj.counter;
}

incrementCnt(myGlobal);
incrementCnt(myGlobal);

console.log(myGlobal.counter);   // 2

This works because when you pass an object to a function, what is passed is a pointer to that same object (the object is not copied). So, if you modify any property on that object, there is only one copy of the object so you are modifying the property on that one copy of the object and everyone who has a reference to that object will see the property change.

Primitives like numbers and booleans are passed by value which works like a copy was made so the original can never be affected from the function.


Can someone explain why number remains unchanged and suggest another way to achieve my intended goal?

When passing a number to a function, the value of the number is copied to a new variable which is the argument to the function. Changing the value of that argument to the function ONLY affects that argument - it has no connection at all to the original variable. This is because in Javascript primitives are passed by value, not by reference. So, no reference is maintained at all to where the value came from. When you receive it in the function, it is a new variable that stands on its own.


Another possible work-around is to just return the modified value from your function and allow the caller to assign that modified value to whatever they want:

var counter = 0;

function increment(val) {
  return val + 10;
}

counter = increment(counter);

console.log(counter);   // 10

If you were to pass in a object instead of a primitive, you would be able to update it.

For example:

var number = { value: 20 };
function setnew(num) {
  num.value += 1;
};

setnew(number);
console.log(number.value) //-> 21

Basically when you pass in an object, javascript is actually only passing a reference to the variable, while when you pass an integer, it is going to pass a copy of the value.

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