When working in the console of developer tools in chrome, I types in,
2 + []
and it produced the unexpected result "2". The same happens with every number. What is happening? Also, when we add some number to a nonempty array, it concatenates the number and the first element of that list, e.g., 2+["abc",6] produces "2abc, 6".
Note: I don't have much experience in js.
This is due to coercion in javascript.
both 2 and [] are tried to get converted to a common type - string.
Now, toString method of array returns "" and toString of Number returns "2" in this case.
Therefore to get the result - "2" after "" and "2" are concatenated.
From What I observe, Javascript does implicit type conversions and if both sides of the operand are different, JS will try to typecast them to string in case of + operation.
For example, if you try [12,34].toString() it will return "12,34" and and if you do 2+[] js will interpret it as 2.toString() + [].toString() thus the output "2".
You can try different combinations in your browser console for more experiments.
Related
I got these 2 examples below -
console.log("a" > "3") // outputs true
console.log("hello" > "3") // outputs true
According to MDN, If both values are strings, they are compared as strings, based on the values of the Unicode code points they contain.
But then they also wrote the following in the next paragraph, Strings are converted based on the values they contain, and are converted as NaN if they do not contain numeric values.
Following this logic, shouldn't both statements be false since no matter what the operator it is, "a" and "hello" are words in strings and they don't have a numerical value, therefore, it should return NaN, and NaN is false; hence, as soon as one of the operands is false, it outputs false?
If I need to adhere to the former statement above, could you please walk me through this logic?
Thanks.
The key phrase from the MDN article is
If both values are strings, […].
Otherwise JavaScript attempts to convert non-numeric types to numeric values
So no, "a", "3" and "hello" are all strings, and when comparing them, they get compared as strings. No conversion to anything occurs.
You are comparing two strings (in quotation marks), not a string to a number. This should answer your question:
"a" > "3" //true
"a" > 3 //false
As you've written,
If both values are strings, they are compared as strings, based on the
values of the Unicode code points they contain
So, on both examples, both values are strings. If you change "3" to 3, the result is:
console.log("a" > 3)
// expected output: false
console.log("hello" > 3)
// expected output: false
That's because, first it's converted as NaN, and then:
If either value is NaN, the operator returns false.
The docs:
If both values are strings, they are compared as strings, based on the values of the Unicode code points they contain.
Otherwise JavaScript attempts to convert non-numeric types to numeric values: ....
Reading the docs, I understand that, if BOTH strings have numerical values (both not NaN), then both are treated as Unicode code points. Otherwise, if BOTH have numerical values, then they're converted.
But anyways, my sugestion for a js beginer: do not get too attached to how the language works for now, and even tho it can compare strings with "greater" and "less than", I dont think there would (or should) be a real life scenario where you would need it.
Also, just for fun, check this pen I made when I first started with js (I was also very confused about comparison and typing xD):
"" == null // this one is fun
Later, after learning more about the language, you'll get why somethings work like they do in js, I also recomending understanding the history of js and the web, it explains a lot of the weird behaviours of the language.
I am building a BODMAS calculator using JavaScript, and working on some code to iterate through all the terms of the equation to find certain mathematical operators and numbers.
var AddPresent = EquationTerms.search(5);
console.log(AddPresent);
If number five is present in the string EquationTerms, it logs the index/position of the number in the string to the console of my browser. If it is not present, it logs -1. While this does not interfere with my program, I am curious: Why does it log -1, and not undefined, or null?
I have searched online, but haven't found an answer which explains the reason. I would be grateful for one which explains this.
This is a pretty common convention, carried over from languages where integers and null were not interchangeable.
A strongly-typed language like C does not let you return null from a function that is declared as returning an integer, so you need to return some integer that denotes "not found". Because there is no way for an element to exist at a negative index, -1 is the most obvious choice.
-1 means "no match found".
The reason it returns -1 instead of "false" is that a needle at the beginning of the string would be at position 0, which is equivalent to false in JS. So returning -1 ensures that you know there is not actually a match.
Why does x = "1"- -"1" work and set the value of x to 2?
Why doesn't x = "1"--"1" works?
This expression...
"1"- -"1"
... is processed as ...
"1"- (-"1")
... that is, substract result of unary minus operation applied to "1" from "1". Now, both unary and binary minus operations make sense to be applied for Numbers only - so JS converts its operands to Numbers first. So that'll essentially becomes:
Number("1") - (-(Number("1"))
... that'll eventually becomes evaluated to 2, as Number("1"), as you probably expect, evaluates to 1.
When trying to understand "1"--"1" expression, JS parser attempts to consume as many characters as possible. That's why this expression "1"-- is processed first.
But it makes no sense, as auto-increment/decrement operations are not defined for literals. Both ++ and -- (both in postfix and prefix forms) should change the value of some assignable ('left-value') expression - variable name, object property etc.
In this case, however, there's nothing to change: "1" literal is always "1". )
Actually, I got a bit different errors (for x = "1"--"1") both in Firefox:
SyntaxError: invalid decrement operand
... and Chrome Canary:
ReferenceError: Invalid left-hand side expression in postfix operation
And I think these messages actually show the reason of that error quite clearly. )
Because -- is an operator in JavaScript.
When you separate the - characters in the first expression, it's unambiguous what you mean. When you put them together, JavaScript interprets them as one operator, and the following "1" as an unexpected string. (Or maybe it's the preceding "1"? I'm honestly not sure.)
"-1" = -1 (unary minus converts it to int)
So. "1" - (-1)
now, "+" is thje concatenation operator. not -. so JS returns the result 2 (instead of string concat).
also, "1"--"1" => here "--" is the decrement operator, for which the syntax is wrong as strings will not get converted automatically in this case.
because -- is an operator for decrement and cannot be applied on constant values.
In JavaScript, variables are loosely typed, so the number 5 and the string "5" may both be treated as a number by several operators. However, is there a generic way to find out JavaScripts conversion abilites in at tunrime, or is it just the overloading of operators for several types that make the loose typing possible?
For example, given a variable a and a string containing a type name type_canditate, is there any way to ask JavaScript, if a may convert to type_candidate in a feasable manner, in contrast to the hard typing operators like instanceof? For example, "5" instanceof Number evaluates false, while Math.sin("5") is perfectly feasable. For numbers, one can obviuosly check if parseFloat(some_number) evaluates to NaN, but this is a special case for numbers.
So, is there any generic way of naming types, and check if some variable may convert to a given type in a useful manner?
There are three primitive data types in JavaScript: string, number and boolean.
Anything can be converted to a string or boolean:
All objects convert to true (except null, which becomes false - I only mention it here because typeof null gives object)
All objects have a built-in toString method which is called when converting to a string.
Converting a number to a string is done by giving the string representation of the number (ie. 5 becomes "5")
Numbers convert to boolean true, unless it's 0 which becomes false.
Converting to a number is a little trickier, but technically possible. If it can find a valid number, then it becomes that number. Otherwise, it becomes NaN.
So basically... any type can become any other type through casting in this way. The only time you have anything resembling an "error condition" is NaN.
In JavaScript, can someone explain the results of the 2 following expressions:
"4" + 4 and 4 + "4"
Thanks!
Both will result in the String:
"44"
This is because the + operator serves 2 purposes -- addition and concatenation. And, if either operand is a String (or is cast to a String by the internal ToPrimitive()) they'll be concatenated.
This is described in the specification as:
7) If Type(lprim) is String or Type(rprim) is String, then
a) Return the String that is the result of concatenating ToString(lprim) followed by ToString(rprim)
8) Return the result of applying the addition operation to ToNumber(lprim) and ToNumber(rprim). See the Note below 11.6.3.
If you want to ensure addition, you can use parseFloat() or the unary + on each:
var a = "4", b = 4;
console.log(parseFloat(a) + parseFloat(b)); // 8;
console.log((+a) + (+b)); // 8, extra parenthesis for clarity
1+'1'+1 = '111'
1+1+'1' = '21'
'1'+(1+1) = '12'
'1'+1+1 = '111'
Javascript performs math until it hits a string and then switches to concatenation, and it also follows regular formula rules run () operations first.
they'll both be '44'. The presence of the '4' as a string casts the whole operation to a string, so the two characters are concatenated.
Cited from: http://javascript.about.com/od/variablesandoperators/a/vop10.htm
One thing that can be confusing to beginners is that JavaScript uses +
with text strings to mean something completely different from what it
means with numbers. While with numbers + means add the numbers
together with text + means concatenate them together. Concatenation
basically means joining one text string onto the end of the first so
that "my"+"book" gives "mybook" as a result. Where beginners tend to
get confused is that while 3+3 gives 6, "3"+"3" gives "33".
You can also use += with text strings to directly add the variable or
text on the right onto the end of the text string variable on the
left.
Mixing Data Types
Additional confusion can arise when you are working with variables
that are of different types. All operations require that the variables
that they are operating on both be of the same type. Before JavaScript
is able to perform any operations that involve two different data
types, it must first convert one of the variables from one type to the
other. You can't add a number to a text string without first either
converting the number to text or the text to a number.
When converting between data types we have two choices. We can allow
JavaScript to do the conversion for us automatically or we can tell
JavaScript which variable that we want to convert.
JavaScript will attempt to convert any text string into the number
equivalent when performing subtraction, multiplication, division, and
taking remainders. Your text string will actually need to contain
something that JavaScript can convert to a number (i.e., a string like
"10") in order for the conversion to work.
If we use + then this could either mean that we want to convert the
string to a number and add then or that we want to convert the number
to a string and concatenate them. JavaScript can only perform one of
these two alternatives. It always converts numbers to strings (since
that will work whether the string contains a number or not).
Here are some examples.
"5" - 3 = 2;
"5" + 3 = "53"
2 + "7" = "27"
5 + 9 + "1" = "141"
Since subtraction only works with numbers 1 converts the text string
into a number before doing the subtraction.
In 2 and 3 the number is converted to a text string before being
concatenated (joined) to the other text string.
In 4 the leftmost addition is done first. Since these are both numbers
they are actually added together and not treated as text. The result
of this first addition leaves us with a similar situation to the third
example and so the result of that addition is converted to text and
concatenated.
To actually force JavaScript to convert a text string to a number we
can use Number("3") or alternatively to force JavaScript to convert a
number to a text string we can use String(5).
Expressions in JS work on two prime principles.
B O D M A(includes concat) S
Left to right order of execution
However, its not straight forward
for + operator
as far as it encounters numbers it will do math addition using left to right execution, However,as soon as it encounters a string, it concatenates the result (that's calculated till encountering a string) with rest of the expression.
//left to right execution
console.log(10+10+"10") //2010, (10+10) of numtype + "10" of stringtype concat(20+"10")
console.log(10+10+"10"+10+10) //20101010,
//(10+10) of number type + "10" stringtype(now since a string is enc.) + (10+10) of number type would act as strings and get concatenated = 20+"10"+"1010"
console.log("10"+[10,10,10]+10) //1010,10,1010
//"10"of stringtype + array of numtypes + 10 of numtype
// "10" concats with first element of array, last number 10 concats with last element of array.
for all other operators such as -,*,/,^...
if all occurrences are numbers/numbers as string, it will do the respective math operation treating "numbers as string" to be numbers.
console.log("10"-10) //0
console.log("10"/10) //1
console.log("10"*10) //100
console.log(10+"10"*10) //110 //BODMAS
console.log(Math.pow(10,"10")) //10000000000
if there are occurrences of non-numeric strings,arrays,objects in the middle of expression that involve (-,*,/,^...)math operations, it will always return NaN
console.log(10-{id:1,name:"hey"}-10) //NaN
console.log(10-10-"hey"-10-10-10) //NaN
console.log("hey"/10) //NaN
console.log("hey"* 3) //NaN
console.log(["hey","hey"]*"3") //NaN
console.log("10"/[10,10,10]/10) //NaN