Operator assigning with a pre-increment - javascript

For looping variables (usually array indexes) I do a lot of pre-incrementing and modulus assigning in a loop. In other languages this would look like
++_index %= LENGTH;
(broken up version on multiple lines)
_index++;
_index = _index % LENGTH;
This of course increases the _index by 1 and then assigns the modulus back to itself.
but I have problems doing this in Javascript I get the horrible ReferenceError: Invalid left-hand side in assignment.
I suspect what it is actually doing is trying to do assign the modulus of a variable called "++_index" which of course, there is none as its invalid.
I tried using parentheses to hopefully have it read it has _index correctly but still this seemed to be a bust.
(++_index) %= LENGTH;
I have resorted to using the broken down version of
++_index;
_index %= LENGTH;
But I cannot find any documentation on the issue at hand. All my google-fu is bringing back people using = within if statements.
Could someone with far superior google-fu direct me to some documentation that can explain this in more depth. As I said, I suspect its trying to do the assignment to ++_index, rather than evaluate it, increment it and pass reference to variable for the next stage of assigning the modulus. But something (or someone) to confirm or deny this would be most beneficial.

The JavaScript prefix increment operator doesn't return a reference, it just returns a value. It's invalid to assign to a number, so that's why it throws a ReferenceError.
You either have to do this:
_index = ++_index % LENGTH;
or this:
++_index;
_index %= LENGTH;
Specification:
Let expr be the result of evaluating UnaryExpression.
Let oldValue be ToNumber(GetValue(expr)).
ReturnIfAbrupt(oldValue).
Let newValue be the result of adding the value 1 to oldValue, using the same rules as for the + operator (see 12.7.5).
Let status be PutValue(expr, newValue).
ReturnIfAbrupt(status).
Return newValue.

Related

Difference between p++ and ++p when using that in a for loop Javascript

This could be a very naive dumb question, but what is the difference in the output of the following 2 condition:
for (var p=0; p<3; p++) {console.log(p)}
//outputs:
0
1
2
for (var p=0; p<3; ++p) {console.log(p)}
//outputs:
0
1
2
'p' result into same output regardless whether I increment the value first and then print it or vice vera. also I do understand the diff between (p++) and (++p), but in this case I'm unable to understand whether at this point in looping will it make it any difference if I were I do either of 2 or if it does make difference how would that impact my program.
Can someone please explain.
Thank
If you dont use the values, after using pre- and post-fix, there is absolutely no difference at all. (exept from performance)
Doing something like this would behave differently, as you can see:
var a = 0;
var b = 0;
var arr = [0,1,2];
console.log(arr[++b]);
console.log(arr[b++]);
console.log(arr[b]);
In this case there is no difference whatsoever as you are not using the value of the expression.
Since you're not assigning the expression to anything, there's no difference apart from a slight performance gain in the pre-incrementer (because a temporary variable is created in order to store the multiple values of p with the post-incrementer). JSBEN.CH.
Just so you know the difference between them:
let var1 = 3;
let var2 = 4;
console.log(var1++); //Outputs the value of var1, then increments it
console.log(++var2); //Increments the value of var2, then outputs it
The += syntax is actually better in this case, because it is easier to read, and it is just a compaction of p = p + 1 - literally no difference, performance-wise or otherwise. This means it's actually faster.
If you put the two plus in front or after the variable/number only makes a different for evaluating it.
Because it is only inportant that the counter is incremented after leaving the block. If this is done before or after doesnt matter. At the end of the call the number is incremented equally.
++p first it will count +1 and then return the result
p++ it will return the value and then add +1
p value will be different at the end of each turn in those 2 cases.
In your example there is no difference.
However if you use the increment ++ or decrement -- operators inside a function the positioning is significant. To quote the article
JavaScript Increment ++ and Decrement --
If the operand is after the variable console.log displays a then it is incremented
let a = 1;
console.log(a++); // 1
console.log(a); // 2
If the operand is before the variable a it is incremented then console.log displays it
let a = 1;
console.log(++a); // 2
console.log(a); // 2
Several other languages such as C and C++ have the same behaviour.
However these operators need to be used with care. See the following stackoverflow answer (albeit it refers to JavaScript, but also applies to C etc)
Why avoid increment (“++”) and decrement (“--”) operators in JavaScript?
In this case there is no difference in pre and post increment.
However in some cases like this can be significant:
here n and i are first evaluated and then incremented
var n=0
var i
for(i=0;n<5;n=i++){}
after the loop n and i look like this: n=5, i=6
here n and i are evaluated first, but i is incremented before entering the cycle
var n=0
var i
for(i=0;n<5;n=++i){}
after the loop n and i look like this: n=5, i=5

How strict is the syntax of a for-loop

So I have a fairly good amount of experience in coding. I've dabbled in Basic, HTML, Javascript, C, and C++, though the ones I've been using most recently are HTML and Javascript.
I am incredibly familiar with the for-loop. I've used it many times to loop through arrays, to operate recursive functions, etc. I know what it does and how to use it, but my question is about how it works.
Premise
In most languages, the basic syntax of a for loop is such:
var upperLimit = 10;
for(var i = 0; i < upperLimit; i++) {
/*Code to be executed*/
console.log(i);
}
In Javascript, this will output the numbers from 0 to 9 in the console.
I know that the parentheses contains 3 parts, each separated by semicolons.
The first is the initialization, which typically sets up the variables to be used to loop the statements.
The second is the condition, which runs before any of the code between the curly braces is executed. If it results in a True, the code is executed. Otherwise, the for-loop stops.
The third is the increment, which contains the last bit of code to be executed in the loop, and, by extension, the last thing executed before the next condition check.
Question
So, again, my question is how strict are these definitions?
The initialization's definition doesn't allow for much. It just says that that line is executed once, it's executed before anything else in the loop, and it's scope is limited to the loop. I can't think of much else you'd want to put in that position other than an iterative variable.
But what about the other two? I've seen codes where the condition is simply a variable, and as long as it's positive (since positive numbers taken as a boolean just covert to true), the loop continues.
Then there's the increment, which seems to be the loosest of these parts. Is it really just the last thing to be executed in a code, or does it explicitly need to iterate the variable declared in the initialization? It seems to be the former for the languages I'm familiar with.
For example, I decided to make a non-standard for-loop, and I came up with this routine:
var numbers = [0,1,2,3,4,5,6,7,8,9];
for(var i = 0;
numbers.length;
console.log(numbers.pop())) {}
It runs exactly as I expected: It outputs each member of the numbers array in the console in descending order, leaving an empty numbers array afterwards, and it's done using what is basically an empty for-loop.
Ending
So are my assumptions correct? If so, are there any practical applications for using a for-loop in a format apart from the one I wrote at the top of this question (possibly closer to he second format)?
Before all, you give a array
var numbers = [0,1,2,3,4,5,6,7,8,9];
The codes below is a correct for loop.
for(var i = 0;
numbers.length;
console.log(numbers.pop())) {}
Javascript defined for like this
for ([initialization]; [condition]; [final-expression])
statement
For you code initialization is 'var i = 0', and execute once at start of loop.
The condition is 'numbers.length', and value is 10. When a number not 0, Javascript will convert it to boolean true. So condition is true.
The final-expression is 'console.log(numbers.pop())'. When execute 'numbers.pop()', numbers.length change to 9. But it still is true.
At second time, condition will return true again. The final-expression is execute too.
Until numbers.length become 0, Javascript convert it to boolean false. The loop will end.
The scope of the initialized variable is not limited to the loop, it's valid for the whole function (undefined before that line). You can initialize multiple variables using a comma. for (var i=0, j=1; i < 10; i++)
The second part, anything that evaluates to a truthy value will cause the loop to keep going:
Truthy: 1, -1, true, "something", {a: 2}
Falsey: 0, false, null, undefined
You could omit this and rely on a break in your code
The third part just lets you update the looping variable, you could omit it and do it within the for loop body.
Here's an answer that provides a nice way to loop that is non-standard, and comes with caveats, please see the link.
var list = [{a:1,b:2}, {a:3,b:5}, {a:8,b:2}, {a:4,b:1}, {a:0,b:8}];
for (var i=0, item; item = list[i]; i++) {
// Look no need to do list[i] in the body of the loop
console.log("Looping: index ", i, "item" + item);
}
In most languages, the basic syntax of a for loop is such:
for(initialization; condition; iteration) {
/*Code to be executed*/
}
Both three are usual expressions and you can use any valid expressions here:
for(
var i=arr.length, othercond=true;
i;
othercond?i--:i++, console.log(i),updateothercond()
);

Weird looking Javascript for loop

I have never seen a JavaScript loop such as this for( ; i-- ; ), used in the code:
uid: function (len) {
var str = '';
var src = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var src_len = src.length;
var i = len;
for (; i--;) {
str += src.charAt(this.ran_no(0, src_len - 1));
}
return str;
}
I understand the behavior, but I would like it if somebody could share some insights about this type of for loop.
This is a syntax of the for-loop construction:
for ([initialization]; [condition]; [final-expression])
statement
In your case for (; i--;) {:
no variables are initialized, because var i = len; inintialized earlier, so it's not needed.
condition part will be truthy until i becomes 0 then loop will terminate. i-- is executed on before each iteration, and due to -- operator it will eventually become 0, so it's falsy, and loop will stop.
since i is decremented in condition part of the loop, final-expression is not needed too. Another way to put it: since i is not used inside the loop, it does not matter whether we decrement it before each loop iteration or after each loop iteration.
That being said, it's better to avoid writing loops like above, as it's pretty confusing and hard to read. Prefer traditional for-loops notation.
From MDN - for - Optional for expressions:
All three expressions in the head of the for loop are optional.
You don't have to specify all three expressions in for loops. For example, for (;;) is a common wa of writing infinite loop.
In your case, while(i--) would have done the same, there is no good reason to write for (; i--;).
I'd also note that for(var i=len;i>=0;i--) is more robust - it protects you from the case len is negative.
This could be rewritten to
uid: function (len) {
var str = '';
var src = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var src_len = src.length;
var i = len;
while (i >= 0) {
str += src.charAt(this.ran_no(0, src_len - 1));
i = i - 1;
}
return str;
}
The for statement creates a loop that consists of three optional
expressions.
Javascript consider 0 == false that's why in the case you presented the loop will run until the i variable became zero. It will loop as many times as the src string size.
Note: i-- uses the variable value then decrements it. Take a look at the following situation:
for(;i--;) { // i = length in the condition
// i === length - 1 here. It will not overflow the array
}
for(;i--;) { // i = 1
// i === 0 here. It will be the last loop
}
for(;i--;) { // i == 0 == false
// Not executed
}
There is nothing wrong.
for(`INIT`;`TEST`;`ACTION`)
{
`WORK`;
}
The INIT (initialization) can be done outside the loop.
var i=0;
for(;i<=100;i++)
//do something
The TEST part yield a result that is either true or false. Now in this case value of i is tested. Until it becomes zero this works.
The ACTION part is generally used to change the loop variable. But you can leave it also or probably add it to the TEST section like it is done here.
Look this examples are going to clear your idea
var i=0;
for( i++; i++; i+=j); //No body
var i=0;
for(;;); //an infinite loop
var i;
for(i=-4;i;i++);//
Even sometimes WORK is placed in ACTION.
Example:
factorial of x
for(var i=1,ans=1;i<=x;ans=ans*(i++));
Which can be written this way also-
var ans=1;
for(var i=1;i<=x;i++)
ans=ans*i;
NOTE: You can write whichever way you want. It doesn't matter as long as you have written the code properly. Get used to this kind of form you will see them a lot.
Though, it is better to write sometimes in compact form , but remember you should keep the readability.
That's just for loop. Before the first semicolon the variable used in the loop is usually declared. But in this case the variable, the variable used in the loop is declared earlier:
var i = len;
^^^
for (; i--;) {...
So there is no need to redeclare.
After the first semicolon, there is a condition for the loop to run (i.e. i<6, i>3, etc). If condition returns false, or 0, the loop is exited. In this case, the loop will be broken out when i is 0. It happens eventually, because -- after i decrements it, and therefore there is no need for the expression, which is the place after the second semicolon is reserved for.
The first parameter of the for loop has already been defined, so the initial comma is there to delimit it's place in the parameter list.

'Reflecting' a Javascript Array - is this legal?

I found myself needing to convert from a small integer into a corresponding, arbitrary string. The obvious way to do this is with an Array. But I also wanted to go back the other way: given the string, find the corresponding integer. Obviously I could do this by Array.indexOf(), but handling the 'no match found' case was a bit awkward. But in Javascript, Arrays are Objects, and Objects have properties, so I tried defining a function:
var reflect = function(array) {
for (var i = 0; i < array.length; i++) {
array[array[i]] = i;
}
};
which adds a property corresponding to each array element. So given:
lighting2 = ['AC', 'HOMEEASY_EU', 'ANSLUT'];
reflect(lighting2);
I can write lighting2[1] giving me 'HOMEEASY_EU'; and also lighting2['HOMEEASY_EU'] which gives me 1. Furthermore, lighting2['FOO'] gives me undefined as it ought to. The Array.length property does not appear to be affected by this 'reflection'. The technique works - at least it works in node.js - but I have never seen it before. Is this 'legal'? Will it cause nasty things to happen? Is it likely to be useable in all Javascript implementations?
Cue the Javascript language lawyers!

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

Categories