I am learning JavaScript, now in the operators chapter. I was wondering why ++true is an invalid expression in JavaScript and +true is just fine. I guess the differences are because of the way ++ (or --) operator work in JavaScript. Just curious to know what happens when ++ is applied.
console.log(+true); // 1, fine
console.log(++true); // SyntaxError
Why true isn't implicitly converted to number and incremented as it is in the case of +.
When the value is stored in a variable, ++ does the expected job, but we can't use it directly on literals.
++ adds 1 to the value in the variable, and also assigns that incremented value back to the variable. This doesn't make sense when the parameter isn't a variable. You can't change the value of true. ++true is equivalent to true = true + 1.
You can't use ++ on any literal, e.g. console.log(++3) is also an error, since it's equivalent to console.log(3 = 3 + 1).
Note that ++ will convert a boolean to an integer if necessary, but it has to be in a variable:
x = true;
console.log(++x);
Because when you use ++ or --, it changes the value of the variable you're operating on.
var a = 1;
console.log(++a);
console.log(a);
console.log(--a);
console.log(a);
By doing ++true you're implying that you're changing the value of true which would be an absolutely terrible thing to do.
Since true is a non-mutable value, you can't use a mutating operator on it.
The ++ and -- pre- and post-decrement operators implicitly modify the operand variable or property. The operand must be something that can appear on the left side of an assignment operator, or else it doesn't make sense to use ++ or --.
The same is true for C, C++, Java, and I imagine most if not all the C-heritage programming languages that include those operators.
The ++ and -- operator changes the value.
In your case you're trying to increment value of boolean or non mutable value which is not possible the way you're doing.
var x = 10;
console.log(++x) // Output 11
console.log(x++) // Output 12
//Or
var y = true;
console.log(y++) //Output 2
In second scenario output is two because true is equal to 1 and false is equal to 0.
Related
Let me start off by saying I understand the difference between =, ==, and
===. The first is used to assign the right-hand value to the left-hand variable, the second is used to compare the equivalency of the two values, and the third is used not just for equivalency but type comparison as well (ie true === 1 would return false).
So I know that almost any time you see if (... = ...), there's a pretty good chance the author meant to use ==.
That said, I don't entirely understand what's happening with these scripts:
var a = 5;
if (a = 6)
console.log("doop");
if (true == 2)
console.log('doop');
According to this Javascript type equivalency table, true is equivalent to 1 but not 0 or -1. Therefore it makes sense to me that that second script does not output anything (at least, it isn't in my Chrome v58.0.3029.110).
So why does the first script output to the console but the second doesn't? What is being evaluated by the first script's if statement?
I dug into my C# knowledge to help me understand, but in C# you cannot compile if (a = 5) Console.WriteLine("doop"); so I had to explicitly cast it to a bool by doing if (Convert.ToBoolean(a = 5)) but then that makes sense it would evaluate to true because according to MSDN's documentation, Convert.ToBool returns true if the value supplied is anything other than 0. So this didn't help me very much, because in JS only 1 and true are equal.
There's a difference between making an abstract equality comparison with == and performing a simple type cast to boolean from a number value. In a == comparison between a boolean and a number, the boolean value is converted to 0 or 1 before the comparison. Thus in
if (true == 2)
the value true is first converted to 1 and then compared to 2.
In a type cast situation like
if (x = 2)
the number is converted to boolean such that any non-zero value is true. That is, the value 2 is assigned to x and the value of the overall expression is 2. That is then tested as boolean as part of the evaluation of the if statement, and so is converted as true, since 2 is not 0.
The various values that evaluate to boolean false are 0, NaN, "", null, undefined, and of course false. Any other value is true when tested as a boolean (for example in an if expression).
Why does an assignment in an if statement equate to true?
It doesn't. An assignment is evaluated as whatever value is assigned.
This expression is a true value:
a = true
But this expression is a false value:
b = false
That's true whether or not you put it in an if statement or not.
For example, in the following JavaScript code, why do we not get errors when using variables, but when a number literal is used, I get an error (running on node v6.9.5)?
let x = 2;
console.log(x++); //2
let y = 2;
console.log(++y); //3
console.log(2++); //ReferenceError: Invalid left-hand side expression in postfix operation
console.log(++2); //ReferenceError: Invalid left-hand side expression in prefix operation
My understanding is that this doesn’t work because you can’t mutate the literal 2. In the previous example, you returned x or y (either before or after incrementing), so it was now equal to +1 its previous value (so x/ y now pointed to 3, rather than 2). However, you can’t increment 2 to be +1 its previous value and then have it point to the literal 3. 2 will always be 2, 2 will never point to 3.
Am I correct in my reasoning?
Literals are constants, and increment/decrement would try to change its argument respectively. But constant values cannot be changed.
It would be the same like coding something like
2 = 2 + 1;
The argument of a increment/decrement operator must be a lvalue -- essentially, it has to be an expression that you could assign a value to. This can be either a variable, or certain types of simple structured expressions (like array[0]++ or object.foo++).
Constants aren't lvalues. You can't assign a value to them (3 = abc), nor can you mutate their values with the increment or decrement operators.
On this code, the first alert box is displaying -3, am just thinking of this. How can this be possible? As to my knowledge on this, is should alert -2, where i am lacking to understand this? please
var x = 6; var y=8;
alert(x++-++y);
alert(x);alert(y);
The ++ unary operator — a legacy from C, maybe B, maybe PL/I — can be used either as a pre-increment or a post-increment operator. If it's placed after an l-value (a variable reference), the value of the expression is the value of the variable before it has been incremented. The expression has the side-effect of incrementing the variable's value and storing it back.
Thus:
the value of x++ is 6, because that's the value of x before being incremented.
the value of ++y is 9, because the ++ operator is being used to pre-increment the variable y
6 - 9 is -3
Many computer instruction set architectures have included pre- and post-increment addressing modes for machine registers and/or memory locations to facilitate various tasks, notably the process of loading values from an area of memory and incrementing an address register in preparation for fetching the next value. I have always strongly suspected that those concepts seeped upwards into higher-level languages to provide analogous conveniences.
There is a difference between the statement x++ and the statement ++x. It is that the former will return the original value of x while the latter will return the new value of x.
As a result, the calculation comes to 6 (the starting value of x) minus 9 (the new value of y).
leading ++ will add 1 to the value after the operation whilst trailing ++ will apply it before the operation. Hence 6-9=-3
x++ returns the value before incrementing, 6.
++y returns the value after incrementing, 9.
6 - 9 = -3
x++ => 6 // postfix
++y => 9 // prefix
so 6 - 9 = -3
According to Postfix / Increment (++) documentation on MDN:
If used postfix, with operator after operand (for example, x++), then it returns the value before incrementing.
If used prefix with operator before operand (for example, ++x), then it returns the value after incrementing.
x++ does not change the x value until after the operation, so it is 6.
++y changes the value before the operation, so the value becomes 9.
The first alert therefore shows -3.
The second alert is not helpful because you are seeing the now-altered value of x (7) instead of 6.
Regarding
p = 0;
(p+1)++;
> ReferenceError: Invalid left-hand side expression in postfix operation
and
p = 0;
++(p+4);
> ReferenceError: Invalid left-hand side expression in prefix operation
I just got a bit of a surprise, as I expected postfix/prefix operators to be ok with working on the resolution of the expression (brackets have the highest operator precedence).
Could someone give me with a line or three to explain what is happening here?
Thanks
EDIT: Thanks for the quick responses, first answer marked as the answer. I feel I should also point people to the indepth answer from #thefourtheye below
++ increments the value of a variable, so it is larger than before. Eg:
var x = 3;
x++;
alert(x); // will show 4
For there to be any point for this, the expression to the left of ++ must be accessible and mutable, otherwise the increment would be possible. Eg:
3++
doesn't make any sense, as 3 is a constant and can't be incremented. We don't want this to be possible:
3++;
alert(3); // outputs 4???
This is why your expression doesn't work. Ie:
var p = 2;
(p + 1)++;
has the same problem as above. (p + 1) will evaluate to 3, and ++ can't change the value of the constant 3.
You are trying to increment (), the increment/decrement operator can be apply on variable, try the sample code
(p++) + 1
OR
(++p) + 1
Remember that when you write p++, that actually gets translated to p = p + 1. The operators ++ and -- are convenience notation for incrementing/decrementing a variable for future use. But how is (p+1)++ or ++(p+4) supposed to be translated? Those sort of imply that 1 or 4 are being incremented/decremented for future use, which doesn't make sense.
When you have an expression like this
(expr)++;
These are the operations JavaScript will do internally
Resolve the actual object referenced by expr.
This step is important, because you can even do something like this
var a = {b: 1};
++a.b;
a.b++;
console.log(a.b);
# 3
Now, JavaScript has to resolve the actual object to be incremented. In this case, it will be b in a.
Get the value at the reference and convert that value to a Number.
This step is also very important, because you may even have values like this
var a = {b: '1'};
console.log(++a.b);
# 2
JavaScript will try its best to get a number value, instead of failing immediately.
Increment the number.
Store the new vale in expr. This is step where your expression is failing.
In your case expr is p + 1, when it is resolved the value would be just a numeral, whose value can never be changed. (You can never change the value of 1 to something else). So, after the incrementing part, when the new value has to be stored back, JavaScript doesn't find a valid reference to store it. That is why it throws this error.
ReferenceError: Invalid left-hand side expression in postfix operation
This error message is actually thrown from internal PutValue method. The very first step goes like this
If Type(V) is not Reference, throw a ReferenceError exception.
Reference: ECMA Script 5.1 Standard Specification for Prefix Increment Operator
var x = null;
+++x generates a ReferenceError, but when I do the same using postfix increment operator +x++, it works just fine.
The LeftHandSideExpression for the ++ operator must not be a number. For instance
1++;
will fail with the same error (invalid increment operand). You can only apply the pre- and postincrement operators on variables/identifiers/expressions.
Since the + sign casts the null value into a number (0), you got the same outcome.
Examples:
var foo = null,
bar = 5;
foo++; // 0
0++; // invalid increment operand
null++; // invalid increment operand
(+bar)++ // invalid increment operand
foo++ +2; // 2
+x++ is split into two steps:
+x initialises x to 0, so it's no longer null.
x++ then increments x, which works since x is no longer null.
+++x is also split into two steps, but in a particular order:
++x is evaluated first, which throws the exception because x is null.
+x would then be evaluated, except you've already had an exception.
I think your assumption was that +++x would be parsed as ++(+x), but it's actually parsed as +(++x). It's an ambiguous-looking syntax, the language designers had to pick one of the two ways to parse it, and from your point of view they chose "the other one".
To be honest, there's absolutely no value in formatting your code this way anyway - all you end up with is dubious-looking code which is destined to confuse people.
if u used the x= 0 ;
x will be initalized with a integer type that will accept the ++x operator while ++(+x)
is like a ++(+null)
so better try to change to X = 0 ;