64

Why does the regular assignment statement (say, x = 5) return the value assigned (5 in this case), while the assignment combined with a variable declaration (var x = 5) returns undefined?

I got the return values by executing these statements in the Chrome browser's Javascript console:

> var x = 5;
undefined
> y = 5;
5
user10165
  • 1,435
  • 2
  • 11
  • 10
  • possible duplicate of [Difference between using var and not using var in JavaScript](http://stackoverflow.com/questions/1470488/difference-between-using-var-and-not-using-var-in-javascript). Take a look at kangax's answer. "`var x = 1` declares variable `x` in current scope (aka execution context).... `x = 1`, on the other hand, is merely a property assignment. It first tries to resolve `x` against scope chain. If it finds it anywhere in that scope chain, it performs assignment; if it doesn't find `x`, only then it creates `x` property on a global object." – Chase Apr 16 '13 at 01:24
  • 3
    that interesting.. I've never noticed this! – anthonybell Apr 16 '13 at 01:26
  • 3
    I think `x = 5` is an expression which is capable of returning a value, while `var x = 5` is a statement which is not. This is most evident by the fact that you can't declare variables inline, i.e `console.log(var x = 5)`. Where are you getting the return value of `undefined` from? – Waleed Khan Apr 16 '13 at 01:26
  • Ordinary assignments are expressions, so you can write `x = y = 5`. This sets `x` to the result of `y = 5`, so the latter need to have a value. You can't write `x = var y = 5` because `var y = 5` is not an expression. – Barmar Apr 16 '13 at 01:27
  • 1
    By what example makes you think that x=5 actually "returns"? – Abby Chau Yu Hoi Apr 16 '13 at 01:34
  • @AbbyChauYuHoi He is just referring to the value of the expression. As in `3 + (x = 5)` "returns" 8. – Paul Apr 16 '13 at 01:36
  • @Paulpro We are guessing "he is". – Abby Chau Yu Hoi Apr 16 '13 at 01:41
  • @AbbyChauYuHoi That's the only thing he could possibly be describing. – Paul Apr 16 '13 at 01:42
  • @WaleedKhan I ran this in (Chrome's) Javascript console. That's where `undefined` was shown as (what I interpreted as) the return value of the expression `var x = 1`. I'm going to clarify my question. – user10165 Apr 16 '13 at 02:28
  • @Chase: the answer you linked explains that `var x = 1` is a variable declaration plus an assignment, while `x = 1` is a property assignment. I agree; in fact, I say this in nearly identical words in my question. What I don't know is why Javascript returns a value from the former but not from the latter. Nothing in the answer you linked addresses this point. – user10165 Apr 16 '13 at 02:36
  • 1
    @AbbyChauYuHoi I don't agree with `return` keyword as well, but my answer was for some reason downvoted. I don't get this people... – Karol Apr 16 '13 at 03:37

5 Answers5

59

That's the way the language was designed. It is consistent with most languages.

Having a variable declaration return anything other than undefined is meaningless, because you can't ever use the var keyword in an expression context.

Having assignment be an expression not a statement is useful when you want to set many variable to the same value at once:

x = y = z = 2;

It can also be used like this:

x = 2*(y = z); // Set y = z, and x = 2*z

However that is not the most readable code and it would probably be better written as:

y = z;
x = 2*z;
Paul
  • 139,544
  • 27
  • 275
  • 264
  • 2
    What would break if Javascript treated a variable declaration as an expression (usable inside other expressions, etc.)? – user10165 Apr 16 '13 at 02:42
  • @user10165 They would have do define more rules and such for example, at what point in the expression is the variable useable. There aren't many use cases for it either, since you can do everything without it. – Paul Apr 16 '13 at 02:55
10

That's because var x = 5; is a variable statement, not an expression.

The behaviour of this statement is described in Section 12.2 of the ECMAScript Language Reference.

  1. Evaluate VariableDeclarationList.
  2. Return (normal, empty, empty).

This is basically a void return value.

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
  • 1
    @user10165 It's basically how the language is designed, and seeing how you can have multiple declarations in a single statement I can imagine why they made it `void` :) – Ja͢ck Apr 16 '13 at 02:52
6

The assignment operator (i.e., the equals sign) (1) assigns the right-side-operand (i.e., a value or the value of a variable, property, or function) to the left-side-operand (i.e., variable or property) and then (2) the assignment expression (e.g., y = 10) becomes a simple operand with the same value as its right-side-operand (e.g., 10) before the rest of the expression is evaluated. This is similar to when a called function is replaced with its return value when an expression is evaluated (although function calls are first in the order of operations and assignment operations are fourteenth):

var x, y, z = 1;
x = z + (y = 2); // x === 3     

function returnTwo () {
    return 2;
}

x = z + returnTwo(); // x === 3

Take note that not only does x now equal 3, but the entire expression evaluates to 3.

The purpose of the var keyword is to bind variables to the current scope. Variables declared with the var keyword are bound to the scope where they are declared. The var keyword assigns the left-most variable (or property) as a reference to the value of the evaluated expression:

var fun = function () {
    var x = 1;
    var y = x + 1; 
    return y;
}

// The x and y variables are bound to the scope of the fun function.

Using the var keyword with an expression is called a declaration. Declarations are actions that do not evaluate to a value, not even undefined (even though your console is printing undefined). Further, declarations cannot appear where JavaScript expects an expression, as other answers to this post have shown.

orb
  • 1,263
  • 1
  • 10
  • 16
  • "The var keyword is a special operator that writes the return value of a statement to memory" So if you don't have `var` then return value of statement is not written to memory? – Karol Apr 16 '13 at 03:31
  • Yeah, I better adjust that. – orb Apr 16 '13 at 03:38
  • Thanks for the help. Sometimes random thoughts about the way Java works creep in my head when I am dealing with JavaScript and I end up having to slap myself upside the head a few times. – orb Apr 16 '13 at 03:52
  • Yeah, would be much simpler if we have only one language! – Karol Apr 16 '13 at 04:17
  • Good point. Well, gotta run -- I am late for a game of ~Darts~!! :-) – orb Apr 16 '13 at 04:31
  • And, even still type declarations in java don't even write to memory. They just assign memory so it can be written to (at least that understanding has worked for me), so I don't know what the heck I was thinking when I wrote that about var. More so, I should probably be flogged for relating var to a type declaration in my thought process in the first place. – orb Apr 16 '13 at 04:35
3

When you write var x = 5; it declares x and initalizes its value to 5.

This is a VariableStatement, it returns nothing,

but x=5 is an expression that assigns 5 to x. as there is no x, JavaScript implicitly creates a global x in normal code

Sachin
  • 40,216
  • 7
  • 90
  • 102
0

I edited my answer because of comment and some other answers.

Assignment operator doesn't return anything... In below example, first thing JS parser does is assigning 5 to y. Second thing is assigning y to x, and so on. Assigning is not return (it's not a function, and in JS it doesn't have C++ syntax to overload operator's behavior). return is sth more complex then assignment. return construct is not only returning a value, but is closing current context causing it to be destroyed. Also it's closing any parent context (closure pattern) if there is no other child using it. So please, DO NOT tell me (in comments) that assignment operator returns any value. Assignment operator in case of JS is only a language construct.

This language construct is useful in chains (and that's why everyone is talking about returning):

a = x = y = 5;

Any undeclared variable is declared automatically by parser in global scope. If you declare variable explicitly, then you can't at the same time use it in chain, like this:

a = var x = y = 5;

Proper use of above code would be:

var x = y = 5;
a = x;

Of course you can use brackets, to make your code clearer, but it doesn't mean that code behaves like a function.

Also your example works only in JS console, which is not returning but printing the result of statement, or expression. It means that JS console treats result of declaring of variable as undefined (same when creating function: function a() {}).

Karol
  • 7,803
  • 9
  • 49
  • 67
  • 1
    You have to use parenthesis because the assignment operator is 14th (next to last) in the order of operations.http://arguments.callee.info/2008/11/03/order-of-operations-in-javascript/ However, saying that an expression returns a value is completely incorrect. Expressions evaluate to a value. You are definitely 100% correct. – orb Apr 16 '13 at 04:04
  • 1
    Thanks. Perhaps it would be less confusing to a novice if javascript console didn't treat the result of a statement to be `undefined` (since nowhere in the language does it say that). Instead, it should have simply printed nothing at all after a statement, and the value of an expression after an expression. – user10165 Apr 16 '13 at 04:14
  • Carlos, you might like my revamped answer. I think the terminology is spot-on now. – orb Apr 16 '13 at 05:58