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

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

Related

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))

Unambiguous increment and adding results in error

When playing around with JavaScript syntax it struck me that the following code will throw an error in SpiderMonkey and V8 engines:
var a = 1, b = 1;
a++++b;
This to me is strange, since the following works perfectly fine:
var a = 1, b = 1;
a+++b; // = 2; (Add a and b, then increase a)
// now a == 2 and b == 1
a+++-b; // = 1; (add a and -b, then increase a)
// now a == 3 and b == 1
In addition, the following would be nonsensical code:
var a = 1, b = 1;
a++ ++b; // throws an error
My argument is now that if a+++b is equivalent to a++ + b, and not to a+ ++b, and a+++-b is equivalent to a++ + -b, then a++++b can only be interpreted as a++ + +b in order for it to be valid JavaScript code.
Instead, the engines insist that a++++b is interpreted as a++ ++b, by operator precedence.
This to me is in contrast with the logic that the engines implements using the / symbol, as explained here, to distinguish between division and regular expressions. An example
var e = 30, f = 3, g = 2;
e/f/g; // == 5
e
/f/g; // == 5
/f/g; // is equivalent to new RegExp("f","g")
Here the argument is that because /f/g does not make sense as division in the last line, it is interpreted as a regular expression.
Obviously the / symbol gets a special treatment, in order to distinguish between division and regular expressions. But then why do ++ and -- not get a special treatment as well? (That is, outside operator precedence)
A second question is why operator precedence is not called only when the code is has multiple valid interpretations.
In the code a++++b you have two distinct statements: a++ and ++b with nothing to combine them. The + operator in the context of a++ + +b is actually a type converter (meant for turning strings into numbers) and has a different order of precedence which follows the others in the list.

Meaning of === with function call

I had been going through the ES6 assuming that it would be easy to switch to EcmaScript 2017.
While going through, I got confused about this code
function f (x, y = 7, z = 42) {
return x + y + z
}
f(1) === 50
Which has ES5 equivalent
function f (x, y, z) {
if (y === undefined)
y = 7;
if (z === undefined)
z = 42;
return x + y + z;
};
f(1) === 50;
I did understand the default parameter thing from it.
But what does f(1)===50 mean in both the codes? Whats the use of it?
Here is another example
function f (x, y, ...a) {
return (x + y) * a.length
}
f(1, 2, "hello", true, 7) === 9
What does f(1, 2, "hello", true, 7) === 9 mean?
I understand that === for comparison between the LHS and RHS of the operator including the type of both and not just value.
But why have it been used like that??
Kindly explain its usage.
This is the link from where I got this. http://es6-features.org/#RestParameter
This is a strict comparison test whether function f(x,y,z), when called with an x parameter value of 1 returns the value 50. This would be true when the default parameter values added to the value of x are 7 and 42.
These function calls and comparisons are purely to provide usage examples and possibly test examples for the functions they call.
The code
function f (x, y, ...a) {
return (x + y) * a.length
}
f(1, 2, "hello", true, 7) === 9
is an example of extended parameter handling. the ...a variables length property equates to 3 thus the test is confirming the number of parameters passed to the function after x and y.
According to me, you almost took it in a correct way.
Just put that function call along with the triple equals sign in if condition.
if ( f(1) === 50 ){
console.log(true);
}
else {
console.log(false);
}
Thats it.
The triple equal to is simply a comparison operator. And the function call on one side of the triple equal to operator means the value returned from that function.
Hence just treat it as any other comparison operator in javascript.
And please correct me if I have misinterpreted your question.!
All the best!
The f(1)===50 checks if f(1) is equal to 50. If this expression is evaluated to true, then the result of this expression is true. Otherwise it is false. Since you don't assign this value to a variable, as it is, you can't use it anywhere.
Formally, the === is called strict equality operator. For further info please have a look here.
The point here is that its example code. They are showing you that the function's results when called with those arguments is equal to something. The expression itself won't do anything, unless you paste it into a console.
They could have just as easily used a comment.
f(1, 2, "hello", true, 7) // 9
The identity (===) operator behaves identically to the equality (==) operator except no type conversion is done, and the types must be the same to be considered equal.
In your example if you will put all three arguments of numeric type you will get number as the result and then to check if the result has correct type you have to use === operator.
Maybe this example will be more clear in your case:
f(1,1,1) // returns 3 - numeric type
f(1,1,"1") // returns "111" - string type
//so now if you will write
f(1,1,1) == "3" // true
f(1,1,1) == 3 // true
f(1,1,1) === "3" // false, because the result is 3 not "3" as string.
f(1,1,1) === 3 // true
f(1,1,"1") == "111" // true
f(1,1,"1") == 111 // true
f(1,1,"1") === "111" // true
f(1,1,"1") === 111 // false, because the result is string "111" not 111 number.
So in your case this === operator is used to double check if the result is really what you expect it to be.

Js magic need explanation

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

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

Categories

Resources