Why can't we increment (++) or decrement (--) number literals - javascript

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.

Related

What does it mean when variable value in round brackets?

What does it mean when variable value in round brackets in js?
For example,
let a = (1,2,3);
What does it mean and why console.log(a) output is 3?
What is usage of comma operator in round brackets in variable initialization?
The parentheses are needed for grouping. In a let statement, commas are normally used to separate multiple variables that are being declared, e.g.
let a = 1, b = 2, c;
which is short for
let a = 1;
let b = 2;
let c;
If you write
let a = 1, 2, 3;
you'll get a syntax error, because after the comma it expects another variable declaration; it's equivalent to:
let a = 1;
let 2;
let 3;
The second and third declarations are clearly wrong, as 2 and 3 are not variable names.
The parentheses indicate that the whole expression 1, 2, 3 is being used to initialize one variable.
The expression 1, 2, 3 uses the Comma operator, which executes each of its subexpressions and returns the last one as its value. It's pretty useless when the subexpressions are all constants, so I assume your code was just a simplified example. Because the way it's written, it's really just equivalent to:
let a = 3;
What you have encountered is the comma operator.
Quoting the docs
The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand.
Therefore in your case 1, 2 and 3 is evaluated and 3 is returned and thus assigned to the variable a.
This is not variable declaration-specific thing. You can write (1,2,3) anywhere in your JS code and it will always evaluate to 3. The thing is, JavaScript (like many other programming languages, e.g. C) has comma operator, which simply returns last element. The expression (1,2,3) basically looks just like (1+2+3) to JavaScript, except for comma operator is applied instead of addition.
It's call the comma operator:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
It's a very handy thing to use in JavaScript, because it allows you to run multiple statements as a single value for an arrow function.
Here is an example of a 10x10 identity matrix generated with one line of code. The last comma value is returned as the value.
const m = new Array(9).fill('000000000').map((v,i)=> (v=[...v],v[i]='1',v.join()));
console.log(m);
The same above code as a blocked function would take a lot more lines.
const m = new Array(9).fill('000000000').map((v,i)=> {
v = [...v];
v[i] = '1';
return v.join()
});
console.log(m);

why ++ or -- can't be applied directly on literals in JavaScript?

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.

Javascript: Mathematical operation methods

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.

Javascript: Why doesn't (p+1)++ work?

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

Why does +++x gives an error message when +x++ works fine?

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 ;

Categories