Js magic need explanation - javascript

I'm trying to solve this magic in js:
var a = 1;
console.log(a++ + ++a);
It returns 4 and I can understand that it's 1+3 but what is the sequence of this?

a++ means return the value before incrementing
++a means returns the value after incrementing
So to break down your example:
var a = 1;
console.log(a++ + ++a);
a is set to 1
a++ returns 1, and then a is incremented to 2 (but we don't do anything with it at this point)
++a increments a and returns 3
Then altogether we have console.log(1 + 3) with the 1 coming from step 1 and the 3 coming from step 3.

what is the sequence of this
In pseudo spec language:
Evaluate addition (a++ + ++a)
Let lval be the result of evaluating the left operand (a++)
Get the value of a and assign it to oldValue. (1)
Let newValue be oldValue + 1.
Assign newValue to a. (a == 2)
Return oldValue. (1)
Let rval be the result of evaluating the right operand (++a)
Get the value of a and assign it to oldValue. (2)
Let newValue be oldValue + 1.
Assign newValue to a. (a == 3)
Return newValue. (3)
Return lval + rval. (1 + 3)
Result: 4

To go into a bit more detail on what Xufox was saying in the comments section:
++a first increments the value of a and then returns an lvalue referring to a, so if the value of a is used then it will be the incremented value.
a++ first returns an rvalue whose value is a, that is, the old value, and then increments a at an unspecified time before the next full-expression (i.e., "before the semicolon").
Postfix increment has higher precedence than prefix increment.
This helped me a lot back in the day and it should help you too..
http://en.cppreference.com/w/cpp/language/operator_incdec

Related

Confused about the postfix increment operator and assignment operator precedence in JavaScript

The operator precedence documentation says that the postfix increment operator have a higher precedence over the assignment operator, but the following example shows that the opposite is true:
var i = 1;
var j = i++;
console.log(j); // will output 1 (I expected the output to be 2)
Why the output is 1 instead of 2?
The post-increment operator increments the value of the variable, but returns the value before it was incremented. Therefore, j will have a value of 1 while i will have a value of 2.
var i = 1;
var j = i++;
console.log("j =", j);
console.log("i =", i);
See increment operator:
If used postfix, with operator after operand (for example, x++), the increment operator increments and returns the value before incrementing.
If used prefix, with operator before operand (for example, ++x), the increment operator increments and returns the value after incrementing.

Why do strings produce a different output for post increment (something++) vs. adding 1 (something = something +1)?

We know about post-increment and pre-increment in programming languages. As far as I know, post-increment means to increment the value for the next statement. So, something++ is the equivalent to something = something + 1, isn’t it?
But why do something = something + 1 and something++ produce a different output when something is a string?
let something = "5";
let anything = 5;
something = something + 1;
console.log(something); // "51"
anything = anything + 1;
console.log(anything); // 6
let something = "5";
let anything = 5;
something++;
console.log(something); // 6
anything++;
console.log(anything); // 6
I know about automatic type-casting, but why is something + 1 coerced into a string, but something++ into a number?
If you read the specification for the ++ operator, you’ll see that step 2 forces its operand to be a number, whereas + doesn’t.
12.4.4 Postfix Increment Operator
12.4.4.1 Runtime Semantics: Evaluation
UpdateExpression : LeftHandSideExpression ++
Let lhs be the result of evaluating LeftHandSideExpression.
Let oldValue be ? ToNumber(? GetValue(lhs)).
Let newValue be the result of adding the value 1 to oldValue, using the same rules as for the + operator (see 12.8.5).
Perform ? PutValue(lhs, newValue).
Return oldValue.
These are two different operators
++ is post increment it implicitly tries to coerce operands to number and then performs increment ++ Ref
let increment = (val) =>{
return val++
}
console.log(increment('5'))
console.log(increment(''))
console.log(increment([]))
console.log(increment({}))
console.log(increment(undefined))
whereas the other one is addition when used for numeric value but works as concatenation for string + Ref
let increment = (val) => {
return val + 1
}
console.log(increment('5'))
console.log(increment(''))
console.log(increment([]))
console.log(increment({}))
console.log(increment(undefined))

Why is n += 1 not equivalent to n++ [duplicate]

I have a very simple arithmetic operator but am at my wits end why it doesn't return 2. The code below returns 1. I thought that x++ equates to x = x + 1;
CODE
var x = 1;
document.write(x++);
However if I run the code as follows, it returns 2 as expected
CODE
var x = 1;
document.write(++x);
What am I doing wrong?
PostIncrement(variable++) & PostDecrement(variable--)
When you use the ++ or -- operator after the variable, the variable's value is not incremented/decremented until after the expression is evaluated and the original value is returned. For example x++ translates to something similar to the following:
document.write(x);
x += 1;
PreIncrement(++variable) & PreDecrement(--variable)
When you use the ++ or -- operator prior to the variable, the variable's value is incremented/decremented before the expression is evaluated and the new value is returned. For example ++x translates to something similar to the following:
x += 1;
document.write(x);
The postincrement and preincrement operators are available in C, C++, C#, Java, javascript, php, and I am sure there are others languages. According to why-doesnt-ruby-support-i-or-i-increment-decrement-operators, Ruby does not have these operators.
I think of x++ and ++x (informally) as this:
x++:
function post_increment(x) {
return x; // Pretend this return statement doesn't exit the function
x = x + 1;
}
++x:
function pre_increment(x) {
x = x + 1;
return x;
}
The two operations do the same thing, but they return different values:
var x = 1;
var y = 1;
x++; // This returned 1
++y; // This returned 2
console.log(x == y); // true because both were incremented in the end
If you take a look at the javascript specification pages 70 and 71 you can see how it should be implemented:
Prefix:
Let expr be the result of evaluating UnaryExpression.
Throw a SyntaxError exception if the following conditions are all true:72 © Ecma International 2011
Type(expr) is Reference is true
IsStrictReference(expr) is true
Type(GetBase(expr)) is Environment Record
GetReferencedName(expr) is either "eval" or "arguments"
Let oldValue be ToNumber(GetValue(expr)).
Let newValue be the result of adding the value 1 to oldValue, using the same rules as for the + operator (see
11.6.3).
Call PutValue(expr, newValue).
Return newValue.
Or more simply:
Increment value
Return value
Postfix:
Let lhs be the result of evaluating LeftHandSideExpression.
Throw a SyntaxError exception if the following conditions are all true:
Type(lhs) is Reference is true
IsStrictReference(lhs) is true
Type(GetBase(lhs)) is Environment Record
GetReferencedName(lhs) is either "eval" or "arguments"
Let oldValue be ToNumber(GetValue(lhs)).
Let newValue be the result of adding the value 1 to oldValue, using the same rules as for the + operator (see
11.6.3).
Call PutValue(lhs, newValue).
Return oldValue.
Or more simply:
Assign value to temp
Increment value
Return temp

Why does this JavaScript function work?

Much apologies for the vague title, but I need to elaborate. Here is the code in question, which I read on http://ariya.ofilabs.com/2013/07/prime-numbers-factorial-and-fibonacci-series-with-javascript-array.html:
function isPrime(i) {
return (i > 1) && Array.apply(0, Array(1 + ~~Math.sqrt(i))).
every(function (x, y) {
console.log(x + ' ' + i % y);
return (y < 2) || (i % y !== 0)
});
}
isPrime(23);
isPrime(19);
isPrime(188);
Just for fun, I added those logs so we can see some output:
undefined NaN
undefined 0
undefined 1
undefined 2
undefined 3
undefined NaN
undefined 0
undefined 1
undefined 1
undefined 3
undefined NaN
undefined 0
undefined 0
This is the first time I have every seen apply and every, so bear with me, but my understanding is that apply basically calls the Array function, where the first argument is the substitution for its this and the second is the output...Never would think that would be useful, but this function seems to work, so...
Here, they seem to be creating an array of length equal to the square root of the number in question. I suppose that makes sense because the square root would be the largest possible factor of the number in question.
OK, so from here, if we were to log that array for, say, the first number, it would look like this:
> var i = 23;
undefined
> Array.apply(0, Array(1 + ~~Math.sqrt(i)));
[ undefined, undefined, undefined, undefined, undefined ]
Great, so it is an array of five undefined. Ok, fine, so from here, the every method is supposed to check whether every element in that array passes the callback function test (or whatever).
The Microsoft documentation specifies three possible arguments for the every method:
value
index
array
Therefore, in this example x is the value, i.e. undefined, and y is the index.
Our output agrees with that conclusion. However, I'm still fuzzy about nested return statements (if the lowest one returns, does its parent also return?), the || operator here (if the first test passes, does the every loop stop?), and just generally how this works.
EDIT
the log should be with an x, not a y. my mistake:
console.log(y + ' ' + i % y); -> console.log(x + ' ' + i % y);
EXPLANATION
So, how did I come across this code, you ask? Well, of course, the simplest way to check for a prime in Java would be like this:
public static boolean isPrime(double num) {
for (double i = 2.0; i < sqrt(num); i++) {
if (num % i == 0.0) {
return true;
}
}
return false;
}
or Python
def isPrime(num):
x = 2
isPrime = True
while x < math.sqrt(num):
if num % x == 0:
isPrime = False
break
x = x + 1
return isPrime
or js
function isPrime(n) {
for (var i = 2.0; i < Math.sqrt(n); i++) {
if (n % i === 0.0) {
return false;
}
}
return true;
}
But say I wanted to check for the largest prime factor of a number like 600851475143 These looping methods would take too long, right? I think this "hack", as we are describing it, may be even less efficient, because it is using arrays instead of integers or floats, but even still, I was just looking for a more efficient way to solve that problem.
The code in that post is basically crap. Teaching people to write code while simultaneously using hacks is garbage. Yes, hacks have their place (optimization), but educators should demonstrate solutions that don't depend on them.
Hack 1
// the 0 isn't even relevant here. it should be null
Array.apply(0, Array(1 + ...))
Hack 2
// This is just Math.floor(x), but trying to be clever
~~x
Hack 3
// this is an outright sin; totally unreadable code
// I bet most people don't know the binding precedence of % over +
y + ' ' + i % y
// this is evaluated as
y + ' ' + (i % y)
// example
2 + ' ' + (5 % 2) //=> "2 1"
I'm still fuzzy about nested return statements (if the lowest one returns, does its parent also return?),
No. A return only return the function the statement exists in
the || operator here (if the first test passes, does the every loop stop?)
No. Array.prototype.every will return false as soon as the callback returns a false. If a false is never returned from the callback, .every will return `true.
function isEven(x) { return x % 2 === 0; }
[2,4,5,6].every(isEven); //=> false, stops at the 5
[2,4,6].every(isEven); //=> true
Here's an example of .every short circuiting
[1,2,3,4,5,6].every(x=> {console.log(x, x<4); return x<4;});
// 1 true
// 2 true
// 3 true
// 4 false
//=> false
See how it stops once the callback returns false? Elements 5 and 6 aren't even evaluated.
... and just generally how this works.
&& kind of works like Array.prototype.every and || kind of works like Array.prototype.some.
&& will return false as soon as the first false is encountered; in other words, it expects every arguments to be true.
|| will return true as soon as the first true is encountered; in other words, it expects only some argument to be true.
Relevant: short circuit evaluation

Why does this condition in a while loop get executed as though it were part of the loop body?

Here's the relevant function (this example is taken from here):
​function factorial (num) {
if (num < 0) {
return -1;
}
else if (num == 0) {
return 1;
}
var tmp = num;
while (num-- > 2) {
tmp = tmp * num;
}
return tmp;
}
console.log(factorial(8));
----> 40320
As I was studying how this function works (and got stumped on the operator precedence in the expression (num-- > 2); kudos to my mentor Edwin Calte at MakerSquare for pointing that out), I noticed that the num variable decrements even though this decrementation is something that is stipulated as a precondition for the loop body to be executed and is not itself part of the loop body. I could understand why it would do that if the expression read instead like:
while (num-- > 2) {
num--;
...}
In the above example, that second num-- isn't necessary for it to work. Another similar expression where this doesn't seem to happen when I run it in my devtools console is:
​if (x - 2 == 5) { x-- }
Here, it seems that if x is 7 then x will decrement by 1, ​not​ that if x is 7 then 2 will be subtracted from x, and then x will decrement by 1. But in the above example with ​num​, the latter principle is what takes effect.
Could someone please explain why?
Because every time the expression num-- is evaluated (which it is on every iteration of the loop to see if the condition is met) it is decreasing num by one. A lot of JavaScript gurus will tell you to avoid num--, num++, --num, ++num exactly because of their not-so-intuitive side effects.
My advice would be to stick with things that are more readable at first glance, even if it is a few more characters to type.
while (num > 2) {
num = num - 1;
}
At the very least, only use them as standalone statements to make what they are doing clear.
while (num > 2) {
num--;
}
In your second example with the expression x - 2 == 5, this expression does not operate on x at all; it doesn't change it's value. You're not assigning anything back to x like you are when you do x--. x--; is exactly equivalent to x = x - 1;. It just so happens that it also returns the value of x before the assignment is made; this way it can be used as the conditional. It's like reading from a variable and then writing to it all in one statement.
num-- does two things: it subtracts 1 from the variable num (assigning the result back to num) and also returns the original value of the num to be used in the rest of the enumpression. So
(num-- > 2)
is short for:
(temp = num; num = num - 1; temp > 2)
Your while loop could be written as:
while (num > 2) {
num--;
tmp = tmp * num;
}
Notice that I no longer have num-- in the while clause. If I did, the variable would get decremented twice: once while testing the condition, and again inside the loop.
x - 2 would express a new value, ie if you opened the console and typed x - 2 it would respond with 5, but that value is not assigned to anything (and thus x is unaffected). The -- and ++ operators are self-contained statements which affect the variable on which they are operating. So your num-- > 2 is the name as saying num > 2 followed by a num = num - 1, which compares the current value, then performs a mathematical operation and assigns the result of that operation to the variable.

Categories

Resources