简体   繁体   中英

Reassigning a global variable from within a function

In one part of a (Udacity) lesson on JavaScript objects, it says that because primitives are immutable, any changes made to an argument inside a function effectively creates a copy local to that function, without affecting the primitive outside of it. This is the example provided:

function changeToEight(n) {
  n = 8; // whatever n was, it is now 8... but only in this function!
}

let n = 7;

changeToEight(n);

console.log(n); // 7

However, as shown in the following example, you can change the value assigned to a global variable from within a function (as long as the variable name isn't passed as an argument):

let counter = 1;

function changeCounter() {
  counter = 2;
}

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

If primitives are immutable, why is the variable mutable in the latter example? Does the example provided in the lesson actually have anything to do with primitives not being immutable, or is it just because the variable name in the function is identical to the name of the argument passed to the function?

Values are immutable, not variables. Variables can be constant but that is a different topic.

Value immutability means that you can't do 1 = 2 or 'hello' = 'world' for it doesn't make sense (in case you have primitive values).

On the other hand, object's are mutable, therefore you can change their internal structure.

obj = {
  name: 'John'
};
obj.name = 'Sue';

But you can make object immutable as well by using Object.freeze(obj) (just be careful because that produces only a shallow immutability).


What you mean is a constant variable - variable that can't be reassigned. So you can't do something like

const x = 1;
x = 2;

But again, you can change the internal state of a value that is stored in a constant variable if it is an object (change in properties of an object doesn't count as reassignment).


In your first example, it actually doesn't matter if it is a primitive value or object. The same thing would occur even if it was an object. It is the reassignment that produces a local copy.

 function changeToEight(n) { n = [8]; } let n = [7]; changeToEight(n); console.log(n); 

Only in-place changes to that object wouldn't produce a new local variable with the same name (for example: Array.prototype.push method, if we consider an array).

 function changeToEight(n) { n.push(8); } let n = [7]; changeToEight(n); console.log(n); 


Your second example is different because function changeChouter doesn't have its own local variable called n . According to scope resolution rules, variables, when referenced, are first searched for in a local scope, if that fails, they are searched for in an enclosing scope next.

That variable n , because it is not local to your function, is searched for in changeChouter 's enclosing scope, which is the global scope in this case, where it is found. Which means that you are reassigning that global variable.

So your code is basically equivalent to

 let counter = 1; counter = 2; console.log(counter); 

function changeToEight(n)

assigns a local variable as n due to the argument, and you are assigning that local variable within the changeToEight function with 8. It's not effecting the global n variable. If you had done like

 function changeToEight(m) { n = 8; // global variable n is now 8...! but local variable m is 7..! } let n = 7; changeToEight(n); console.log(n); // 8 cool..! 

all would be as expected...

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