1

so a quesiton I had for a js interview was basically involving scope and variables in an inner function for example supposed you had this:

function(){
var a=b=3;
}

obviously, b is not defined so it has become a global variable, now what happens when you change b in the global scope, does the value of a change also?

I'm not sure how to test this, but for example, if you changed b to 10, would a also now be 10 or would it remain 3?

3
  • Why would a change if b did? It wouldn't even if they were both global. Commented Jul 10, 2016 at 7:04
  • @nnnnnn im not sure what the context is where variables are reference by other variables and in that case they can change when another one does Commented Jul 10, 2016 at 7:07
  • JS variables don't refer to other variables, they refer to values/objects. Commented Jul 10, 2016 at 7:10

2 Answers 2

8

obviously, b is not defined so it has become a global variable

Only in loose mode. Don't use loose mode. :-) Use strict mode, where it will be the error it always should have been.

now what happens when you change b in the global scope, does the value of a change also?

No, there is no link between a and b at all. Variables contain values (more on this below). When you do a = b, the value in b is copied to a. No link between the two variables is created.

The interviewer may be asking a trick question (they do so love to do that) and/or he/she may be falling into a common error, so keep reading... :-)

I'm not sure how to test this

Since we're in loose mode, we know that a raw function call will set this to refer to the global object during the call. Since the implicit b global will be a property of the global object, we can check it by changing this.b (the global):

function foo() {
  var a = b = 3;
  console.log("(Before) a is " + a + ", b is " + b);
  this.b = 10;
  console.log("(After) a is " + a + ", b is " + b);
}
foo();

(On browsers we could use window instead of this above, as window is a default global on browsers that refers to the global object.)

It's worth pointing out that while there is only one b, there will be a different a for each call to foo in the above. But I don't think it really affects the question.


In a comment you asked about "reference variables." There are no "reference variables" in JavaScript. You're probably thinking about object references. Key fact coming up: It makes no difference to what we're talking about (will changing b change a?) whether the variable contains an object reference or a primitive. But it's a common error people fall into (possibly even the interviewer asking the question :-) ) to think that it matters. But they're confusing changing b (the variable) with changing the state of an object b refers to.

Variables contain values. When you assign an object reference to a variable, that object reference is a value that tells the javaScript engine where the object is in memory. For instance:

var b = {answer:42};

In memory, we have:

                 +------------+
[b:REF55134]-----|  (object)  |
                 +------------+
                 | answer: 42 |
                 +------------+

The value in b is a reference to the object. I've represented it above as REF55134, but we can never actually access the raw value of that reference. That raw value doesn't matter, it's just a thing (akin to a number) that tells the JavaScript engine where the object is.

Now if we do this:

var a = b;

...we copy the value of b into a, and get this in memory:

[b:REF55134]--+
              |   +------------+
              +-->|  (object)  |
              |   +------------+
[a:REF55134]--+   | answer: 42 |
                  +------------+

a and b have the same value in them, and so they both point to the same object.

Changing b will still have no effect at all on a. Where people get confused is that if we change the state of the object b points to, naturally we can see that changed state through a as well. The value in b didn't change, the state of the thing it's pointing to changed.

E.g.:

b.question = "Life, the Universe, and Everything";

Gives us:

[b:REF55134]--+
              |   +------------------------------------------------+
              +-->|                   (object)                     |
              |   +------------------------------------------------+
[a:REF55134]--+   | answer: 42                                     |
                  | question: "Life, the Universe, and Everything" |
                  +------------------------------------------------+

b didn't change, the object changed. So naturally if we did console.log(a.question);, we'd see the famous question, because a and b point to the same object.

If we actually change b, it has no effect on a at all:

b = {foo:"bar"};
                  +------------+
[b:REF14359]----->|  (object)  |
                  +------------+
                  | foo: "bar" |
                  +------------+

                  +------------------------------------------------+
[a:REF55134]----->|                   (object)                     |
                  +------------------------------------------------+
                  | answer: 42                                     |
                  | question: "Life, the Universe, and Everything" |
                  +------------------------------------------------+

Note that now b has a different value in it, referring to a different object.

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

4 Comments

ah thats what i thought, but i also remember something about reference variables where it is possible to change the value of one by changing another but forgot the context in which that occurs.
@codemonkey: There are no "reference variables" in JavaScript. You're probably thinking about object references. I'll add a note about them.
@T.J.Crowder maybe im thinking of it in c# than. Because I remember something about refernece variables but i think it was another language.
@codemonkey: Yes, C# has something called pass-by-reference (function arguments you use the ref or out keywords with). JavaScript doesn't have pass-by-reference at all, it's a purely pass-by-value language. But it does have object references (which are values), which confuses people. (The word "reference" in pass-by-reference means a reference to a variable, not an object, but since it's the same word it's understandably confusing.) I've added a discussion of them above.
2

In this case, since 3 is a primitive type of number. So it's using a primitive data type for the b assignment and the a assignment. Primitive values in JavaScript define immutable values. Which means that the value it has will not change in any way from under you.

The question is a bit misleading though. The value of a will be different if b is changing each time the function is invoked. Each time it is a different variable a though, not the same one. a goes out of scope immediately though, so who cares about a? The function is equivalent to one with a body of b = 3. On a side note, modifying any kind of global state in a function is bad design.

ECMAScript 6 defines seven data types (Boolean, Null, Undefined, Number, String, Symbol, Object), with all being primitive except for Objects.

It would be good to mention explicitly in an interview that you understand that with Objects it would be different assuming a wasn't going out of scope instantly. In that case changing a property on b would also be reflected in a. But changing b completely would not have an effect on a. Why? Because when you're changing a property, you're changing the mutable value, not the variable. You could go further and explain that using the wrapper object Number works differently too.

You'd also get bonus points for mentioning that the code he provided is not valid in strict mode. You can indicate you're using strict mode by using "use strict"; at the top of your file, or you can also scope strict mode to within a function only by making it the first statement in your function. In the ES6 module system, strict mode is turned on by default.

On a side note, since a goes out of scope right away, the question is so bad that it could indicates a bad coder interviewing you. In every implementation of JavaScript I know about, it is not a multi threaded environment...

8 Comments

"In this case, since 3 is of type Number" 3 is number (the primitive), not Number (the object type), and the type of 3 makes no difference whatsoever to whether changing b later will have an effect on a.
You're referring to Number being a constructor, there's a Number type as well, if you don't believe me check here tc39.github.io/ecma262/#sec-terms-and-definitions-number-type
Of course the type of 3 doesn't matter since a goes out of scope and JS is a single threaded environment. But if it didn't go out of scope it would absolutely matter if 3 was instead some other object and a property on that object was changed.
That's not changing b; that's changing the state of what b points to, a fundamentally different thing. (And JavaScript isn't single-threaded.) Re the other, I'm very familiar with the spec. There are number primitives, and Number objects (conventionally written that way, e.g., with the name of the constructor). 3 is a primitive.
Oh I know you understand it. :-) Anyway, I can see your point wrt the interviewer's question. Best,
|

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.