What does the preceding `+` do when defining SVG varaibles in D3? [duplicate] - javascript

I was perusing the underscore.js library and I found something I haven't come across before:
if (obj.length === +obj.length) { ... }
What is that + operator doing there? For context, here is a direct link to that part of the file.

The unary + operator can be used to convert a value to a number in JavaScript. Underscore appears to be testing that the .length property is a number, otherwise it won't be equal to itself-converted-to-a-number.

According to MDN:
The unary plus operator precedes its operand and evaluates to its
operand but attempts to converts it into a number, if it isn't
already. For example, y = +x takes the value of x and assigns that to
y; that is, if x were 3, y would get the value 3 and x would retain
the value 3; but if x were the string "3", y would also get the value
3. Although unary negation (-) also can convert non-numbers, unary plus is the fastest and preferred way of converting something into a
number, because it does not perform any other operations on the
number. It can convert string representations of integers and floats,
as well as the non-string values true, false, and null. Integers in
both decimal and hexadecimal ("0x"-prefixed) formats are supported.
Negative numbers are supported (though not for hex). If it cannot
parse a particular value, it will evaluate to NaN.

It's a way of ensuring that obj.length is a number rather than a potential string. The reason for this is that the === will fail if the length (for whatever reason) is a string variable, e.g. "3".

It's a nice hack to check whether obj.length is of the type number or not. You see, the + operator can be used for string coercion. For example:
alert(+ "3" + 7); // alerts 10
This is possible because the + operator coerces the string "3" to the number 3. Hence the result is 10 and not "37".
In addition, JavaScript has two types of equality and inequality operators:
Strict equality and inequality (e.g. 3 === "3" expresses false).
Normal equality and inequality (e.g. 3 == "3" expresses true).
Strict equality and inequality doesn't coerce the value. Hence the number 3 is not equal to the string "3". Normal equality and inequality does coerce the value. Hence the number 3 is equal to the string "3".
Now, the above code simply coerces obj.length to a number using the + operator, and strictly checks whether the value before and after the coercion are the same (i.e. obj.length of the type number). It's logically equivalent to the following code (only more succinct):
if (typeof obj.length === "number") {
// code
}

Related

Why is 1 == '1\n' true in Javascript?

The same goes for '1\t' (and probably others).
if (1 == '1\n') {
console.log('Equal');
}
else {
console.log('Not Equal');
}
As said before if you compare number == string, it will automatically try to convert the string to a number. the \n and \t are simply whitespace characters and therefore ignored.
This and similar behaviour can be rather confusing leading to situations like this:
(Picture taken from: https://www.reddit.com/r/ProgrammerHumor/comments/3imr8q/javascript/)
The equality operator(==) converts the operands if they are not of the same type, then applies strict comparison. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.
1 is of type Number hence '1\n' is converted to Number first then comparison takes place!
And Number() constructor will convert the string('1\n') to 1 :-
Number('1\n') === 1
In Strict equality using ===, Neither value is implicitly converted to some other value before being compared. If the values have different types, the values are considered unequal.
Hence 1 === '1\n' will be expressed as false

Javascript Simple Boolean Arithemetic

I’ve heard of boolean arithmetic and thought of giving it a try.
alert (true+true===2) //true
alert (true-true===0) //true
So algebra tells me true=1
alert (true===1) //false :O
Could someone explain why this happens?
=== is the strict equality operator. Try == operator instead.
true==1 will evaluate to true.
The strict equality operator === only considers values equal if they
have the same type. The lenient equality operator == tries to
convert values of different types, before comparing like strict
equality.
Case 1:
In case of true===1, The data type of true is boolean whereas the type of 1 is number. Thus the expression true===1 will evaluate to false.
Case 2:
In case of true+true===2 and true-true===0 the arithmetic operation is performed first(Since + operator takes precedence over ===. See Operator Precedence) and then the result is compared with the other operand.
While evaluating expression (true+true===2), the arithmetic operation true+true performed first producing result 2. Then the result is compered with the other operand. i.e. (2==2) will evaluate to true.
Because comparing data TYPE and value (that's what operator '===' does ), TRUE is not exactly the same as 1. If you changed this to TRUE == 1, it should work fine.
At the beginning, you're doing bool + bool. The + operator takes precedence over the === operator so it's evaluated first. In this evaluation, it's converting the booleans to their number forms. Run console.log(true + true); and this will return 2. Since you're comparing the number 2 to the number 2, you get a return value true with the strict equality.
When you're just comparing true === 1, like everyone else said you're comparing the boolean true to the number 1 which is not strictly equal.
first 2 expression are true because you are using expression (true+true) (true-true) it convert type of a value first due to expression and check equality with "===", toNumber and toPrimitive are internal methods which convert their arguments (during expression ) this is how conversion take place during expression
That's why true+true equal to the 2
In your third expression you are using === this not convert arguments just check equality with type, to make it true both values and there type must be same.
Thats all

Why does string to number comparison work in Javascript

I am trying to compare a value coming from a HTML text field with integers. And it works as expected.
Condition is -
x >= 1 && x <= 999;
Where x is the value of text field. Condition returns true whenever value is between 1-999 (inclusive), else false.
Problem is, that the value coming from the text field is of string type and I'm comparing it with integer types. Is it okay to have this comparison like this or should I use parseInt() to convert x to integer ?
Because JavaScript defines >= and <= (and several other operators) in a way that allows them to coerce their operands to different types. It's just part of the definition of the operator.
In the case of <, >, <=, and >=, the gory details are laid out in §11.8.5 of the specification. The short version is: If both operands are strings (after having been coerced from objects, if necessary), it does a string comparison. Otherwise, it coerces the operands to numbers and does a numeric comparison.
Consequently, you get fun results, like that "90" > "100" (both are strings, it's a string comparison) but "90" < 100 (one of them is a number, it's a numeric comparison). :-)
Is it okay to have this comparison like this or should I use parseInt() to convert x to integer ?
That's a matter of opinion. Some people think it's totally fine to rely on the implicit coercion; others think it isn't. There are some objective arguments. For instance, suppose you relied on implicit conversion and it was fine because you had those numeric constants, but later you were comparing x to another value you got from an input field. Now you're comparing strings, but the code looks the same. But again, it's a matter of opinion and you should make your own choice.
If you do decide to explicitly convert to numbers first, parseInt may or may not be what you want, and it doesn't do the same thing as the implicit conversion. Here's a rundown of options:
parseInt(str[, radix]) - Converts as much of the beginning of the string as it can into a whole (integer) number, ignoring extra characters at the end. So parseInt("10x") is 10; the x is ignored. Supports an optional radix (number base) argument, so parseInt("15", 16) is 21 (15 in hex). If there's no radix, assumes decimal unless the string starts with 0x (or 0X), in which case it skips those and assumes hex. Does not look for the new 0b (binary) or 0o (new style octal) prefixes; both of those parse as 0. (Some browsers used to treat strings starting with 0 as octal; that behavior was never specified, and was [specifically disallowed][2] in the ES5 specification.) Returns NaN if no parseable digits are found.
Number.parseInt(str[, radix]) - Exactly the same function as parseInt above. (Literally, Number.parseInt === parseInt is true.)
parseFloat(str) - Like parseInt, but does floating-point numbers and only supports decimal. Again extra characters on the string are ignored, so parseFloat("10.5x") is 10.5 (the x is ignored). As only decimal is supported, parseFloat("0x15") is 0 (because parsing ends at the x). Returns NaN if no parseable digits are found.
Number.parseFloat(str) - Exactly the same function as parseFloat above.
Unary +, e.g. +str - (E.g., implicit conversion) Converts the entire string to a number using floating point and JavaScript's standard number notation (just digits and a decimal point = decimal; 0x prefix = hex; 0b = binary [ES2015+]; 0o prefix = octal [ES2015+]; some implementations extend it to treat a leading 0 as octal, but not in strict mode). +"10x" is NaN because the x is not ignored. +"10" is 10, +"10.5" is 10.5, +"0x15" is 21, +"0o10" is 8 [ES2015+], +"0b101" is 5 [ES2015+]. Has a gotcha: +"" is 0, not NaN as you might expect.
Number(str) - Exactly like implicit conversion (e.g., like the unary + above), but slower on some implementations. (Not that it's likely to matter.)
Bitwise OR with zero, e.g. str|0 - Implicit conversion, like +str, but then it also converts the number to a 32-bit integer (and converts NaN to 0 if the string cannot be converted to a valid number).
So if it's okay that extra bits on the string are ignored, parseInt or parseFloat are fine. parseInt is quite handy for specifying radix. Unary + is useful for ensuring the entire string is considered. Takes your choice. :-)
For what it's worth, I tend to use this function:
const parseNumber = (str) => str ? +str : NaN;
(Or a variant that trims whitespace.) Note how it handles the issue with +"" being 0.
And finally: If you're converting to number and want to know whether the result is NaN, you might be tempted to do if (convertedValue === NaN). But that won't work, because as Rick points out below, comparisons involving NaN are always false. Instead, it's if (isNaN(convertedValue)).
The MDN's docs on Comparision states that the operands are converted to a common type before comparing (with the operator you're using):
The more commonly used abstract comparison (e.g. ==) converts the operands to the same Type before making the comparison. For relational abstract comparisons (e.g., <=), the operands are first converted to primitives, then to the same type, before comparison.
You'd only need to apply parseInt() if you were using a strict comparision, that does not perform the auto casting before comparing.
You should use parseInt if the var is a string. Add = to compare datatype value:
parseInt(x) >== 1 && parseInt(x) <== 999;

Javascript 0 == '0'. Explain this example

I found these examples in another thread but I don't get it.
0 == '0' // true
0 to the left I converted to false(the only number that does that). The right is a non empty string which converts to true.
So how can
false == true --> true
What have I missed?
Here is an official answer to your question (the quoted parts, link at the bottom) and analysis:
Equality (==)
The equality operator converts the operands if they are not of the same type, then applies strict comparison. If either operand is a number or a boolean, the operands are converted to numbers if possible; else if either operand is a string, the string operand is converted to a number if possible. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.
Syntax
x == y
Examples
3 == 3 // true
"3" == 3 // true
3 == '3' // true
This means, as I read it, that the first 3 (integer) is converted to string to satisfy the comparison, so it becomes '3' == '3', which is true, same as in your case with zeroes.
NOTE: I assume that the converion may vary in different JS engines, although they have to be unified under ECMAScript specifiction - http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3 (quoted #Derek朕會功夫). This assumption is made on a subjective and imperative opinion that not all browsers and JavaScript engines out there are ECMAScript compliant.
Identity / strict equality (===)
The identity operator returns true if the operands are strictly equal (see above) with no type conversion.
The Identity / strict equality (===) found on the same resource at the end of the answer will skip the automatic type conversion (as written above) and will perform type checking as well, to ensure that we have exact match, i.e. the expression above will fail on something like:
typeof(int) == typeof(string)
This is common operator in most languages with weak typing:
http://en.wikipedia.org/wiki/Strong_and_weak_typing
I would say that one should be certain what a function/method will return, if such function/method is about to return numbers (integers/floating point numbers) it should stick to that to the very end, otherwise opposite practices may cut your head off by many reasons and one lays in this question as well.
The above is valid for other languages with weak typing, too, like PHP for example.
Read more of this, refer second head (Equality operators):
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators
When you use == JavaScript will try very hard to convert the two things you are trying to compare to the same type. In this case 0 is converted to '0' to do the comparison, which then results in true.
You can use ===, which will not do any type coercion and is best practice, to get the desired result.
Equality operator
The equality operator converts the operands if they are not of the same type, then applies strict comparison. If either operand is a number or a boolean, the operands are converted to numbers if possible; else if either operand is a string, the string operand is converted to a number if possible. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.
Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators
JavaScirpt Table Equality: http://dorey.github.io/JavaScript-Equality-Table/

how a string object transforms when compared?

console.log("20">10); //true
console.log("20a">"10"); //true
console.log("20a">10); //false
I want to know why the last one turns false.
And "20a" transforms to what before comparing.
From the MDN page on comparison operators:
For relational abstract comparisons (e.g. <=), the operands are first converted to primitives, then the same Type, before comparison.
console.log("20">10); //true
This converts "20" to a number 20 and compares it. Since 20 is greater than 10, it is true.
console.log("20a">"10"); //true
This compares the two strings. Since "20a" is greater (alphabetically) than "10", it is true.
console.log("20a">10); //false
This converts "20a" to a number. The result is NaN (do +"20a" to see this in action). NaN is not greater than any number, so it returns false.
The comparison algoritm in ECMAScript is described here : http://bclary.com/2004/11/07/#a-11.8.5
The comparison x < y, where x and y are values, produces true, false,
or undefined (which indicates that at least one operand is NaN). Such
a comparison is performed as follows:
Call ToPrimitive(x, hint Number).
Call ToPrimitive(y, hint Number).
3.If Type(Result(1)) is String and Type(Result(2)) is String, go to step 16. (Note that this step differs from step 7 in the algorithm for
the addition operator + in using and instead of or.)
4.Call ToNumber(Result(1)).
5.Call ToNumber(Result(2)).
...
So in case of "20a">10, the javascript engine must apply ToNumber to "20a". The complete algorithm is complex but states that
If the grammar cannot interpret the string as an expansion of
StringNumericLiteral, then the result of ToNumber is NaN.
So you're comparing NaN to 10 and any comparison involving NaN returns false (or undefined, see comments below).
For the last case, Notice that even "20a" < 10 return false. This highlights the evaluation of "20a" at NaN during the comparison, as NaN compared to any number always returns false.

Categories

Resources