Inline `++` in Javascript not working - javascript

Astonished to find out that a line like this :
$('#TextBox').val(parseInt($('#TextBox').val())++ );
Will not work !
I've done some tests, it plays out to the conclusion that the inline ++ doesn't work (in Javascript as a whole ? Or simply in my example ?).
Here's a test with three pieces of code, it seems that ++ is ok with a variable but not inline.
So, no inline ++ for us in Javascript?

There's nothing particular to jQuery about this. ++ increments a variable. You are trying to increment the return value of a function call.

Q: What does x++ mean?
A: x++ means take the value of x, let's call this n, then set x to be n + 1, then return n.
Q: Why does this fail on a non-variable?
A: Let's try it on something simple, say 3, and see where things go wrong.
Take the value of 3 and call it n, okay, n = 3
Set 3 to be n + 1, so 3 = 3 + 1, 3 = 4 this makes no sense! So if this step can't be done, the ++ operator can't be used.

++ works on variables, not directly on numbers
var c = parseInt($('#TextBox').val());
$('#TextBox').val( ++c );
Change the order from
var x = 0;
var result = x++;
result // 0
To
var x = 0;
var result = ++x;
result // 1
Then it will evaluate ++ before retrieving the value.

Related

Prefix and postfix operators [duplicate]

This question already has answers here:
javascript i++ vs ++i [duplicate]
(8 answers)
Closed 10 months ago.
let a = 70;
a++; // This returns the value before incrementing.
console.log(a) // returns 71
Can someone explain to me why this doesn't return 70, please?
let b = 70;
++b; // Using it as a prefix returns the value after incrementing.
console.log(b) // returns 71
I understand how prefix works.
I have read explanations and watched videos on this subject but it's still confusing to me. Thank You.
Both versions of them increment the value they're applied to. If you do nothing with the value of the increment expression itself, they're equivalent, both of them doing the same thing as i += 1. The only time it matters is when you use the result of the increment expression:
let a = 70;
console.log(a++); // outputs 70, the old value of a, but a will be 71 afterwards
console.log(a) // outputs 71; no matter how you increment, after the increment, the value has changed
let b = 70;
console.log(++b); // outputs 71; the new value of b is produced
console.log(b) // outputs 71; same as in case a
The difference you are trying to notice is only visible when you use these prefix/postfix operators inline, something like this:
let a = 5;
console.log(a++);
let b = 5;
console.log(++b);
"return" isn't the right term (functions return, expressions do not).
a++ evaluates as the value before incrementing.
You aren't looking at the value the expression evaluates as, you are just looking at the value of the variable after the increment.
let a = 70;
let result_of_a_plus_plus = a++; // This evaluates as the value before incrementing.
let b = 70;
let result_of_plus_plus_b = ++b; // Using it as a prefix increments the value before the expression is evaluated.
console.log({
a,
result_of_a_plus_plus,
b,
result_of_plus_plus_b
});

Postfix operator in JavaScript [duplicate]

This question already has answers here:
++someVariable vs. someVariable++ in JavaScript
(7 answers)
Closed 4 years ago.
This is a basic JS question I think, but I just couldn't find an answer that I was satisfied with. I'm learning operators in JavaScript and I can't understand this following postfix example and how it works:
var x = 4;
var y = x++;
For example, when I alert x, it gives me 5. But when I alert y, it gives me 4. And I can't understand the logic behind it.
I understand that, because it's a postfix, x is assigned to y. And y reads just x, without the postfix. But why does then the original x read the postfix instead if I'm applying it to a different var?
If I just did var y = x + 1, the original x would stay unchanged. But that's not the case when I use postfix. Why would I even change the x with this method? Couldn't I just go then var x = 4; x++; ? And not bother changing it via another var?
I apologize if this is too basic and thanks in advance!
It's easier to think of the increment operators as little functions that return something. So x++ is a functions that increments x and returns the original value of x, whereas ++x does the same thing but returns the new value.
This comes in handy from time to time especially in loops where you want precise control of the stopping point. For example, compare:
let i = 0, j = 0;
while (++i < 5) {
console.log(i) // stops at 4
}
while (j++ < 5) {
console.log(j) // stops at 5
}
The difference is because the while loop evaluates one before the increment and the other after.
Similarly in recursive functions you'll often see things like:
function recurse(i) {
if (i == 5) return i
console.log(i)
return recurse(++i)
}
console.log("final: ", recurse(0))
But if you use the postfix return recurse(i++) you get infinite recursion.
Why would I even change the x with this method?
For some funny shortforms like:
const array = [1, 2, 3];
let i = 0;
while(i < array.length) console.log(array[ i++ ]);
Couldn't I just go then var x = 4; x++; ?
Yeah or just prefix, like ++x or just x += 1 which is more appropriate in most cases.

post-increment operator with shorthand assignment

I have a simply array and counter:
var data = [1];
var i = 0;
The shortcut assignment produces 2:
data[i++] *= 2
// 2
I was expecting 3. data[i++] is multipled with 2, so 1 * 2 is 2, and then that is assigned to data[i++], which now becomes 2, and then after statement evaluated the side effect of ++ causes i to be 3.
The following also gives me unexpected result. It produces NaN oddly enough.
var data [1];
var i = 0;
data[i++] = data[i++] * 2;
// NaN
I was expecting 3 again. data[i++] first evaluates to 1, and then is multipled with 2, and then that 2 value is assigned to i in data[i++], which is then incremented after statement completes, causing it to be 3.
What am I missing here?
var data [1]; is not a valid JavaScript. Did you mean var data = [1];?
data[i++] *= 2 is evaluated as follows:
i++, as the innermost expression resolves first: its value is i (i.e. 0), and i increments afterwards to 1.
data[0] is looked up, and multiplied by two; since data[0] is 1, data[0] gets assigned the value of 1 * 2, i.e. 2.
The value of the outermost expression is returned: 2. ++ increments only what it was applied to (i), and not the whole expression.
data[i++] = data[i++] * 2 evaluates as follows:
The first i++ evaluates to 0 and modifies i to 1, as before.
The second i++ evaluates to 1 and modifies i to 2
The expression then evaluates as data[0] = data[1] * 2. data[1] is undefined, and undefined * 2 is not a number (NaN).
In general, it is strongly recommended to avoid having two increment/decrement operators in the same expression. Different languages (and indeed, different compilers of the same language) have wildly different ideas of what should be done. In many languages, it is declared "undefined behaviour" in language specification.
Instead of i++, use ++i. In your case, you're first returning i, then incrementing it, while you're looking for an increment, and return it after.

weird syntax for "for" loop

Today I came across the following JS:
for (var b = k, d = function (c) {
// function body
}, a = b.p, e = z; 0 < c;) {
} // for loop closing cause
Can some please explain what's happening here? I'm confused about the function, normal "for" loop would do:
for(x=0; x<something; x++){
}
This loops appears to follow a different structure:
for(x=0; d = function(c), a = somevar, e = somevar, 0 < c)
Why are there 5 elements in the for loop? Thanks!
for (var b = k, d = function (c) {}, a = b.p, e = z; 0 < c;) {
} // for loop closing cause
for(x=0; x<something; x++)
If you map the first for loop with the signature for loop...
The code in bold is the declaration part for different variables that are going to be used inside the for loop.. .. Any number of variables can be declared here...
The second is the check condition...
And the third part is empty
There are not five parts, only three:
The first one contains four variable declarations (b, d, a and e).
The second one contains a comparison (0 < c).
The third one is empty.
Each part is separated by semicolons (;) and the variable declarations are separated by commas ,.
The first part is allowed to contain either an expression or a variable declaration list. For more information, have a look at the specification or the MDN JavaScript documentation:
initialization
An expression (including assignment expressions) or variable declaration. Typically used to initialize a counter variable. This expression may optionally declare new variables with the var keyword. These variables are not local to the loop, i.e. they are in the same scope the for loop is in. The result of this expression is discarded.
Only because for(x=0; x<something; x++) is the most typical form, does not mean others don't exist. Each part can contain an arbitrary expression. For example, a useful way to iterate over all children of a DOM element is the following:
for(var node = element.firstChild; node; node = node.nextSibling) {
}
First, node is initialised with the first child of the element. The second part just tests whether node is not null (you could also write node !== null explicitly) and the third part (executed after the iteration) assigns the next child to node.
Ill explain, but basically this is not good code.
Its not good code because you need to go online just to figure it out.
for (var b = k, d = function (c) {
// function body
}, a = b.p, e = z; 0 < c;) {
} // for loop closing cause
is the equivalent of
var b = k,
d = function (c) {
// function body
},
a = b.p,
e = z;
for (; 0 < c; ){
}
for loop parents has three parts
1. Initialization
2. Condition
3. Ending statement
That must all be separated by a ;
except these are all optional in a for loop
for (var init = 0; init < 10; init += 1) {}
same as:
var init = 0;
for (;;) {
if (!(init < 10)) {
break;
}
init += 10;
}
The control variables in a loop can also be a valid expressions as you have in your example.
The first loop you posted is slightly different from the last. The first declares and assigns several variables (one of which is a function), then provides a condition (0<c), then does nothing every iteration. The last seems invalid.
The problem with the first one seems to be only that it does not intialize a c, so unless c is a variable from outside of the scope of the loop that is somehow being changed inside its body, the loop will either not run at all (if c>=0) or it will run forever (if c is indeed less than 0).
for (var b = k, d = function (c) {
// function body
}, a = b.p, e = z; 0 < c;) {
} // for loop closing cause
as long as d is not 0 the for loop will run. d is 0 when 0 < c

The "unexpected ++" error in jslint [duplicate]

This question already has answers here:
Why avoid increment ("++") and decrement ("--") operators in JavaScript?
(17 answers)
Closed 5 years ago.
What is the best practice for that then?
Jslint explains that it "adds confusion". I don't see it really...
EDIT: The code, as requested:
var all,l,elements,e;
all = inElement.getElementsByTagName('*');
l = all.length;
elements = [];
for (e = 0; e < l; (e++))
{
if (findIn)
{
if (all[e].className.indexOf(className) > 0)
{
elements[elements.length] = all[e];
}
} else {
if (all[e].className === className)
{
elements[elements.length] = all[e];
}
}
}
The longstanding best practice: use i += 1 instead, following jslint's advice.
As for why it is a better practice than ++, according to Crockford:
The increment ++ and decrement -- operators make it possible to write in an extremely terse style. In languages such as C, they made it possible to write one-liners that: for (p = src, q = dest; !*p; p++, q++) *q = *p; Most of the buffer overrun bugs that created terrible security vulnerabilities were due to code like this. In my own practice, I observed that when I used ++ and --, my code tended to be too tight, too tricky, too cryptic. So, as a matter of discipline, I don’t use them any more.
Edit: Included comment from Nope as this answer continues to get views.
Just add /*jslint plusplus: true */ in front of your javascript file.
To avoid confusion, and possible problems when using minifiers, always wrap parens around the operator and its operand when used together with the same (+ or -).
var i = 0, j = 0;
alert(i++ +j);
This adds i and j (and increments i as a side effect) resulting in 0 being alerted.
But what is someone comes along and moves the space?
var i = 0, j = 0;
alert(i+ ++j);
Now this first increments j, and then adds i to the new value of j, resulting in 1 being alerted.
This could easily be solved by doing
var i = 0, j = 0;
alert((i++) +j);
Now this cannot be mistaken.
Personally, I prefer to put statements such as i++ on a line by themselves. Including them as part of a larger statement can cause confusion for those who aren't sure what the line's supposed to be doing.
For example, instead of:
value = func(i++ * 3);
I would do this:
value = func(i * 3);
i++;
It also means people don't have to remember how i++ and ++i work, and removes the need to apply quite so many preference rules.
The real problem of the ++ operator is that it is an operator with side effects and thus it is totally opposed to the principle of functional programming.
The "functional" way to implement i++ would be i = i + 1 where you explicitly reassign the variable with no side effects and then use it.
The possibility of confusion is that ++ does two things by adding a value AND reassigning it to the variable.
JSLint friendly loop
for (i = 0; i < 10; i += 1) {
//Do somthing
}
Please note that the ++ operator depends on position with respect to the prior/next variable and the newline / semicolon to determine order of operations.
var a = 1;
var b = a++;
console.log(b); // b = 1
console.log(a); // a = 2
var a = 1;
var b = ++a;
console.log(b); // b = 2
console.log(a); // a = 2
There is something called a pre-increment: ++i and a post-increment i++
and there is a difference:
var i = 9;
alert(++i); //-> alerts 10
var j = 9;
alert(j++); //-> alerts 9
alert(j); //-> alerts 10 now, as expected
var k = 9;
alert((k++)); //-> still alerts 9 even with extra parentheses

Categories

Resources