An interesting thing I've never seen before was posted in another question. They had something like:
var i = + +1;
They thought the extra + converted it to a string, but they were simply adding to a string which is what caused it to convert.
This, however, lead me to the question: what is going on here?
I would have actually expected that to be a compiler error, but JavaScript (at least in Chrome) is just fine with it... it just basically does nothing.
I created a little JSFiddle to demonstrate: Demo
var i = 5;
var j = + +i;
document.body.innerHTML = i === j ? 'Same' : 'Different';
Anyone know what's actually occurring and what JavaScript is doing with this process?
I thought maybe it would treat it like ++i, but i doesn't increment, and you can even do it with a value (e.g., + +5), which you can't do with ++ (e.g., ++5 is a reference error).
Spacing also doesn't affect it (e.g., + + 1 and + +1 are the same).
My best guess is it's essentially treating them as positive/negative signs and putting them together. It looks like 1 == - -1 and -1 == + -1, but that is just so weird.
Is this just a quirky behavior, or is it documented in a standard somewhere?
Putting your the statement through the AST Explorer, we can see that what we get here is two nested Unary Expressions, with the unary + operator.
It's a unary expression consisting of + and +i, and +i is itself a unary expression consisting of + and i.
The unary expression with the unary + operator, will convert the expression portion into a number. So you're essentially converting i to a number, then converting the result of that to a number, again (which is a no-op).
For the sake of completion, it works on as many levels as you add:
var i = 5;
console.log(+ + + + + +i); // 5
console.log(i); // still 5
It's in the specification.
Digging through, we can see from §14.6.2.2 that the increment and decrement operators are listed before (and should be preferred) over the unary operators. So precedence alone won't explain this.
Looking up the the punctuation table in §11.7, we can see that every single instance of ++ (the operator) in the spec shows the two together, without whitespace. That's not conclusive, until you check...
The whitespace rules in §11.2, specifically:
White space code points may occur within a StringLiteral, a RegularExpressionLiteral, a Template, or a TemplateSubstitutionTail where they are considered significant code points forming part of a literal value. They may also occur within a Comment, but cannot appear within any other kind of token.
JS does not allow arbitrary whitespace mid-operator.
The JS syntax in both PegJS and Esprima corroborate this, matching on the literal two-character string ++.
For me it's very clear;
var a = +3;
var b = +a; // same as a, could be -a, for instance
var c = + +a; // same as above, same as +(+a)
If you do ++variable the javascript interpreter sees it as the increment operator.
If you do + +variable the javascript interpreter sees it as Unary plus, coercing the value to a number, twice.
So
var a = 1;
var b = +a;
var c = +b;
console.log(c);// still 1
is the same as
var c = + +1;
So the simple answer is that two plus signs can not be separated by a space to be interpreted as incrementation, the space makes it so the interpreter sees two seperate spaces, which is what it really is
The + operators converts into a number, two + operators with a space in between does nothing additional.
Even though it might look very similar, + + and ++ are not at all the same thing for an AST interpreter. The same applies to token separation: varfoo is not the same as var foo.
In the expression + + +i, each + is considered as distinct unary operator, which simply convert your variable to a number. For the incrementation operation, which is ++, no spaces are allowed, neither between the + and the variable token. In the example below, the last line is not valid:
var x = "4";
console.log(+ + +x);
console.log(+ + ++x);
console.log(+ ++ +x);
Related
This question already has an answer here:
What does this symbol mean in JavaScript?
(1 answer)
Closed 2 years ago.
I am working through some basic JS stuff on W3 schools and the following code is not making much sense to me:
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Statements</h2>
<p>A <b>JavaScript program</b> is a list of <b>statements</b> to be executed by a computer.</p>
<p id="demo"></p>
<script>
var x, y, z; // Statement 1
x = 5; // Statement 2
y = 6; // Statement 3
z = x + y; // Statement 4
document.getElementById("demo").innerHTML =
"The value of z is " + z + ".";
</script>
</body>
</html>
Specifically what I am having trouble with is the 'the value of z is " + z + "."'
You can think of the operator + as a function that takes two arguments, say a and b.
Let's replace, for clarity, the + operator with the keyword add. Then, our function signature looks like add(a, b).
If you let a and b be two integers, say a = 1 and b = 2, then you probably expect add(a, b) to perform the arithmetic operation of addition and output number 3.
Perhaps, the confusing part is when a and b are not integers, or more generally of numeric type. It turns out that our add function has what's called an overload. What this means is that our function does different things based on the type of input you provide to it. When a and b are integers, add(a, b) adds a and b up. In your example, it happens that the function arguments are of type string. So, instead of performing addition, the function performs concatenation (e.g., putting two things together, just like putting together words forms sentences).
Now, back to the + operator. This is just syntactic sugar. Same may argue that it feels more natural to write a + b than add(a, b). It definitely is shorter.
In your example, the operator + is used two times.
"The value of z is " + z + "."
Let's break it down:
// A string.
"The value of z is "
// A number.
z
// A string.
"."
By doing "The value of z is " + z the operator is trying to do some work on a string and a number. The default behavior in this case is to type cast z as a string and then perform concatenation. Thus, at the end of this operation the output becomes the string "The value of z is 11". Next, you are using again the + operator, but this times on two strings, namely "The value of z is 11" and ".". So, the default in this case is to just concatenate those two strings. Therefore, your output becomes "The value of z is 11."
I'm both a JavaScript / Node n0ob....but I was recently working on a project using both. I was exploring the /node_modules/ folder and I came across a particular line of code that didn't seem to immediately make sense to me. The goal is to determine if a number is odd or not.
The specific line of code is:
return !!(~~i & 1);
My question is 'Why do we need the ~~'
(related to: How to determine if a number is odd in JavaScript which shows most of the answers using % 2)
I think I understand the individual pieces.
!! is the negation operator (twice) and will give us a true/false value from a truthy/falsey value
~~ is a way to truncate a value. 8.234 becomes 8.
& is the bitwise and operator.
But I'm still questioning if we need the ~~, and if so, why?
I've been using N..toString(2) - for example:
4.0.toString(2)
> "100"
4.1.toString(2)
> "100.0001100110011001100110011001100110011001100110011"
To try and understand what the binary representations look like. In the second example, the right-most digit is a 1, but when I plug 4.1 in as the value for i, it still correctly sees that the number is even:
!!(~~4.1 & 1)
> false
!!(4.1 & 1)
> false
I've read that Javascript uses the IEEE 754 standard, and I've also read that all of the bitwise operators being used here do some implicit converting that I don't fully understand and maybe there are considerations that I'm not seeing?
Thanks
The double ~~ is used to convert a string to an number, just like !! is used to convert a truthy/falsey value to a boolean.
var a = "4";
console.log(typeof a + " " + a); //string
console.log(typeof ~a + " " + a); //converts to number, but you get (a - 1)
console.log(typeof ~~a + " " + a); // reverses the previous operation, keeping the number type
Now, as you realized, it's not necessary in this operations because in Javascript, when you do bitwise operations on strings they're first converted to numbers, so the double tilde becomes superfluous.
What I suspect was the intention of the maker of that snippet is that you can't really classify a decimal number as odd or even, so he just cast it as a number to get rid of the decimals, which ~~ does.
This question already has answers here:
Why does JavaScript handle the plus and minus operators between strings and numbers differently?
(7 answers)
Closed 5 years ago.
Why does Javascript give an output of 0 when I use the odd operator?
What is the difference between subtraction and addition with a string?
var x = 1;
console.log(x+'1') // Outputs 11
console.log(x-'1') // Outputs 0 -- but why?
So how can I do mathematical calculations?
The + operator has one of two three meanings in javascript. The first is to add numbers, the second is to concatenate strings. When you do 1 + '1' or '1' + 1 the operator will convert one operand that is not a string to a string first, because one other operand is already evaluated to be a string. The - operator on the other hand has just one purpose, which is to subtract the right operand from the left operand. This is a math operation, and so the JS engine will try to convert both operands to numbers, if they are of any other datatype.
I'm not sure though why typecasting to strings appears to have precedence over typecasting to numbers, but it obviously does.
(It seems to me the most likely that this is a pure specification decision rather than the result of other language mechanics.)
If you want to make sure that the + operator acts as an addition operator, you can explicitly cast values to a number first. Although javascript does not technically distinguish between integers and floats, two functions exist to convert other datatypes to their number equivalents: parseInt() and parseFloat() respectively:
const x = 10;
const result = x + parseInt('1'); // 11
const y = 5;
const result2 = y + parseFloat('1.5'); // 6.5
const result3 = y + parseInt('1.5'); // 6
Edit
As jcaron states in the comment below, the + operator has a third meaning in the form of an unary + operator. If + only has a right operand, it will try to convert its value to a number almost equivalent as how parseFloat does it:
+ '1'; // returns 1
+ '1.5'; // returns 1.5
// In the context of the previous example:
const y = 5;
const result2 = y + +'1.5'; // 6.5
Dhe difference with parseFloat is that parseFloat will create a substring of the source string to the point where that substring would become an invalid numeric, whereas unary + will always take the entire string as its input:
parseFloat('1.5no-longer-valid'); // 1.5
+ '1.5no-longer-valid'; // NaN
That is because + is a concatenation operator. So javascript considers it to be a concatenation operator rather than a mathematical operator.But it is not the case with / ,* ,/ etc.
This happens because + its also used to concatenate strings. Then, JS always will find the better way to make the correct typecasts basing on types. In this case, the x+'1' operation, will be identified as string type + string type.
Otherwise, x-'1', will become int type - int type.
If you want to work with specific types, try to use type cast conversions, link here.
Was reading through Douglas Crockford's code here and saw a line
var value = +node.getValue();
but I don't see anything at http://www.w3schools.com/js/js_operators.asp which corresponds to an = + or a way that + can be used as a unary operator. So what does this mean?
The - and + operators are both unary in JS and, before forcing the value's sign, must convert the value to a number.
Obviously - will convert to a number and invert the sign, but + only does the first part. Running +"100" will return the number 100.
This behavior is explicitly stated in the spec at 11.4.6, where the unary + operator is defined:
The unary + operator converts its operand to Number type.
It's just a quick way to make sure the variable is an INT, (vs. a STR or BOOL, e.g.).
Just to add on to what's been said do the following:
var a = +'4';
var b = '4';
console.log(typeof(a));//Number
console.log(typeof(b));//String
By this I mean NOT the default javascript behavior of string + number = string, or string + string = string. From http://www.javascriptkit.com/jsref/arithmetic_operators.shtml, the Unary plus will convert a string to a number.
So how would I specify that I want numeric addition with two strings? This seems to work, but is somewhat ugly:
var a = "5";
var b = "2";
var c = +a + +b;
Does there exist a (numeric only +) operator, that always returns a number? Can one be defined like in other languages? For examples, perhaps '%%' or '+^' or '+++'? Or is this just not possible?
No. If you want to perform numeric addition than you have to ensure that both sides of the expression are Numbers before you start.