I'm trying to understand what exactly the double exclamation mark does. Yes, I saw this question, with lots of answers. So I know in principle what it does, but I don't know why one would ever need to use it.
From what I understand, it converts the value to a boolean. So let's say I have the following code:
var myBool = !!(index === 0 || index > len);
Can't I just leave out the !! and I will get the same result:
var myBool = (index === 0 || index > len);
What do I gain by adding !!? Is't it already a boolean vaule?
The purpose of !! is to canonicalize any type of truthy or falsey value to the corresponding boolean value.
If the value is already known to be a boolean, such as the result of a comparison operator, there's no point in it and it's redundant. So it's useless in the example you gave.
Related
I have been given a Javascript code, and there is a sentence I cannot fully understand:
var isFaculty = (paramArray[0] == "yes"),
isFaculty variable is used afterthat in a equation, where more variables are involved. While the latter are defined along the code, the former is supposed to be defined (i.e. numerical value) by that sentence, as it depends on a parameterArray that the user should introduce (the parameter array is of size 3, anyway). For cell [0], paramArray can have two values, namely "yes" or "no".
I am wondering a possibility, but any help is welcome.
Thanks in advance,
/Jorge.
(paramArray[0] == "yes")
This is like a mini if statement that returns either true or false.
isFaculty is a boolean variable that captures that result.
Once the true or false is caught it can be used as a numeric 1 or 0 that even though is not recommended but could be multiplied by a number to turn it into a 0 if it's false or leave it unchanged if it's true
thanks for your help. The point is that isFaculty variable is involved in a formula as follows:
var xExample = 1/(1+Math.exp(-(-2 + 4*city - 0.11*gender + 0.6*isFaculty + 0.2*city*gender - 0.424885*city*isFaculty - 0.3*citygenderisFaculty)));
consequently, I understand that isFaculty gets value 1 or 0 depending on being true or false?
== is a comparator that will return a boolean value, so the code you have will assign true or false to isFaculty
The var name isXxxx would suggest to me that its value would be boolean.
So what you have is basically:
var isFaculty - for the variable isFaculty
= - assign the value of the following expression
paramArray[0] - take the first value from the array paramArray
== - check if it matches in content but not necessarily type with
"yes" - the string value that you are looking for to assign true
Implicitly this also means that if the content of paramArray[0] does not match with the content of the string value "yes" then the value of isFaculty will be false.
This could be used as a 'flag' later on by using false as 0 and true as 1.
I work with WebStorm 2016.2.2, TypeScript 2.1, Node.js.
For some reason, isNaN is declared as a function that only accepts a number:
declare function isNaN(number: number): boolean;
I tried to change it to any, but it looks like it doesn't influence on the TSC. I still get the same error:
Argument of type 'string' is not assignable to parameter of type
'number'
My code (simplified):
isNaN("10");
How can I solve/workaround it?
Edit:
Notice that according to specification, isNaN's parameter can be any type: Number.isNaN()
Also: My code was simplified. I actually receive a parameter that may be either a string or a number, and if it's a string it may be either a stringy number that I would like to convert to number ("10") or a simple string ("Hello world").
I didn't want to make this question long by including my entire code, but because it caused confusion, this is my real code:
if (typeof expectedValue === "string" && !isNaN(expectedValue)) {
expectedValue = +expectedValue;
}
if (typeof actualValue === "string" && !isNaN(ctualValue)) {
actualValue = +actualValue;
}
switch (this.operator) {
case Operator.equal:
return actualValue == expectedValue;
case Operator.notEqual:
return actualValue === undefined || actualValue != expectedValue;
case Operator.greaterThan:
return actualValue > expectedValue;
case Operator.littleThan:
return actualValue < expectedValue;
case Operator.greaterOrEqual:
return actualValue >= expectedValue;
case Operator.littleOrEqual:
return actualValue <= expectedValue;
}
I advise you to implement your code differently.
The reasons:
It might be short, but it's not easy to understand what's going on
Using isNaN isn't the best option here: isNaN("") returns false as well
You better try to convert the value into a number and check if that's NaN or not (as #smnbbrv wrote):
if (typeof expectedValue === "string" && !Number.isNaN(Number(expectedValue))) {
expectedValue = Number(expectedValue);
}
Edit
You can pass your value as any:
isNaN(ctualValue as any)
To bypass the compiler check.
You should not solve it because this is how TypeScript works.
Just cast the input to number first
Number("10") // 10
Number("abc") // NaN
and then check the result with the isNan function:
isNaN(Number("abc"))
As ironically only numbers can be NaN, you need to transform strings into numbers first.
A very simple way to do this is the unary plus operator.
So you can do a simple isNaN(+"10").
Keep in mind that thing like +"", +" " and +"\n" are 0!
First of all, only values of type number can be NaN. So if the static context tells you your value is of type string for example, you can be sure that it is not a NaN. If you have a value with type string|number (which should be avoided btw) you can still decide how you handle this. Strictly speaking, the string value "foo" is not NaN, as NaN is a specific value specified in the IEEE standard for float numbers. But still, in javascript, isNaN("foo") will be true, as the function will coerect the string to a number first, and that coerection results in a NaN. Typescript tries to take advantage of types here, it tries to prevent you from using isNaN where you should not.
You can solve this by using parseInt inside your isNaN. The check isNaN will still work if the parseInt returns NaN. And your Typescript error will be solved.
if (typeof actualValue === "string" && !isNaN(parseInt(actualValue, 10))) {
actualValue = +actualValue;
}
In the accepted answer, !Number.isNaN(Number(expectedValue)) still returns true for empty string ('') and whitespace strings (' '). And converting these to number will result in 0.
I'm not a JavaScript developer, and – especially coming from .Net – it looks insane to me as well, but this is what I've done that seems to work:
private static isNumber(value: any): boolean {
return (typeof value === 'number' && !isNaN(value))
|| ((typeof value === 'string') && value.trim() != '' && !isNaN(Number(value)))
}
If you know a saner solution, be sure to edit this!
console.log(isNumber([])); // false
console.log(isNumber({})); // false
console.log(isNumber("")); // false
console.log(isNumber(" ")); // false
console.log(isNumber(" 1 ")); // true <= note
console.log(isNumber(" 1 2")); // false
console.log(isNumber("1")); // true
console.log(isNumber(1)); // true
Found this answer from Google, and reached my answer from the various answers and comments here; my answer is to use:
isNaN(Number(string))
This will correctly tell me if the string is a number.
I was previously using parseInt(), but this fails if the string is something like 123abc as parseInt just discards the letters (useful sometimes, but not here).
Note: I'm happy that Number('') evaluates to zero, but if your not, this isn't the solution!
Passing isNaN(value as unknown as number) satisfied my compiler.
In my case, I was using isNaN() to prevent "NaN" from flashing while data loaded. This allowed me to pass a string into isNaN() since the interface expected a string.
I created a javascript method that checks if a number is a float. Each time I test the method for a float it keeps returning FALSE. I am not sure what I am doing wrong here. Any help would be really appreciated!
Below is my code.. Thanks!
function isFloat(n){
var patt = new RegExp('[+-]([0-9]*[.])?[0-9]+');
return patt.test(n)
}
console.log(isFloat(12.40));
There's a much easier way to check if a number is a float. Just compare the floored value against the original value. If they're the same, it's an integer.
function isFloat(n) {
return Math.floor(n) !== n;
}
console.log(isFloat(1));
console.log(isFloat(1.2));
console.log(isFloat(12));
console.log(isFloat(12.4));
This will work if, and only if, you only use it on numbers. You can perform an additional check if you're worried about someone passing in non-numbers.
function isFloat(n) {
return typeof n === 'number' && Math.floor(n) !== n;
}
Or you can simplify this even further by using Number.isInteger, provided you're running an environment that supports it.
function isFloat(n) {
return typeof n === 'number' && !Number.isInteger(n);
}
console.log(isFloat(1));
console.log(isFloat(1.2));
console.log(isFloat(12));
console.log(isFloat(12.4));
console.log(isFloat('a'));
Your RegEx is wrong, it should be
/[+-]?\d+\.\d+/g
Also, as others noted, this is not the best solution for this. Use !Number.isInteger(num)
The problem is that toString does not insert '+' before a number:
12.40.toString(); // "12.4", not "+12.4"
So you could use a regular expression like
new RegExp('[+-]?([0-9]*[.])?[0-9]+');
However, I recommend Validate decimal numbers in JavaScript - IsNumeric()
I am still learning, so I'm sorry if my question is not well formatted.
I was trying to write a function to insert a word to a string in a specified position, however I made a mistake which is writing two equal signs == rather than one in the execution block and this resulted in wrong output when tested.
However, I already know that the execution of code after if/else needs to not be boolean and I noticed this typo and I corrected it by removing one equal sign and the function worked perfectly fine but I was just left wondering why have I never questioned the significance of strictly having one equal sign when executing code after if conditionals.
so here is the wrong code:
function insert(original,to_insert,position){
if (to_insert == "undefined" && position == undefined){return original;}
else if (position == undefined){position == 0}
var x = original.slice(0,position);
var y = original.slice(position);
console.log(x + to_insert + y);
}
insert('We are doing some exercises.','JavaScript ');
//Wrong output >>>> "We are doing some exercises.JavaScript We are doing some exercises."
insert('We are doing some exercises.','JavaScript ', 18);
//correct output>>>> "We are doing some JavaScript exercises."
and here is the correct code:
function insert(original,to_insert,position){
if (to_insert == "undefined" && position == undefined){return original;}
else if (position == undefined){position = 0}
var x = original.slice(0,position);
var y = original.slice(position);
console.log(x + to_insert + y);
}
insert('We are doing some exercises.','JavaScript ');
//correct output >>>> JavaScript We are doing some exercises."
insert('We are doing some exercises.','JavaScript ', 18);
//correct output>>>> "We are doing some JavaScript exercises."
would you please explain what happens inside my wrong code, like what causes the function to not run properly when booleans were used, obviously the function runs once at a time, so what difference would an absolute value of position make compared to a variable value of position.
Thanks in advance
else if (position == undefined){position == 0}
In your wrong code, position remains undefined since you did not do an assignment, you simply checked if position (which is undefined) is equal to 0
So, when you did var x = original.slice(0,position); slice() simply ignored the 2nd argument, which in this case is undefined and sliced from start to end, which is the default behaviour in case the 2nd argument is not used.
From MDN:
The slice() method extracts a section of a string and returns a new string.
str.slice(beginSlice[, endSlice])
endSlice
Optional. The zero-based index at which to end extraction. If omitted, slice() extracts to the end of the string. If negative, it is treated as sourceLength + endSlice where sourceLength is the length of the string (for example, if endSlice is -3 it is treated as sourceLength - 3).
In your case, since you pass undefined (because position == undefined), it's like you omitted it
One equal is to assign values to variables, two equals are for camparing two variables. This is the simplest way to explain it.
= - assigning operator
== - comparing operator
if (position == undefined){position == 0}
This mean if your position is undefined position must be 0. Like it should be 0 but you are not defining it. Two equals is usually use to do comparution actually : does position is equals to 0
However one equal mean you assign the value 0 to position.
I can see two problems in your code.
if (to_insert == "undefined" && position == undefined){return original;}
Here you are checking if to_insert is equal to the string "undefined", but not undefined.
else if (position == undefined){position == 0}
Writing position == 0 will just return a boolean. So in this case, it'll return false (because it execute only if position == undefined returns true).
So it's like if in your code, you had a false between two lines, and you don't change the value of any variable.
else if (position == undefined){position = 0}
By writing only one =, you assign the value 0 to the variable position.
So, when you call the slice() method, the second argument is still undefined, so the method ignore it and just slice the string to the end.
Hope I helped you understand !
You're essentially asking, "What is the difference between using one equals sign (=) and using two equals signs (==)?"
Assume we have the following initialization for both examples:
var pikachu_hp;
One equality sign (=):
pikachu_hp = 50;
This sets the variable, pikachu_hp, to have the Number data type with a value of 50.
Two equality signs (==):
pikachu_hp == 60;
This compares the value (not data type, that's three (===) equals signs in JavaScript) of pikachu_hp against what is on the right hand side; in this case, that's the Number 60. If pikachu_hp has a data value of 60, the expression returns true. If pikachu_hp has a data value of anything else but 60, the expression returns false. Again, I call this an "expression" because it does not equate to anything; it represents either a true or false value.
I have a pretty much simple logic in a return function, but it doesn't work as expected. Of course I can make the code slightly longer and solve the issue, but I want it to be as small as possible.
Here is my code:
#Return title if exists or false otherwise
getPageTitleFromMainContent = (mainContent) ->
mainContent.find('#pageTitle') ?.length ?= false
if y = (getPageTitleFromMainContent $("#mainContent"))
y.css color:red
As you see, if it finds the #pageTitle in #mainContent, it should make it red. But the function doesn't return the #pageTitle if found, it returns .length.
From js2coffee.org I see that the code is compiled into:
var getPageTitleFromMainContent, y;
getPageTitleFromMainContent = function(mainContent) {
var _ref, _ref1;
return (_ref = mainContent.find('#pageTitle')) != null ? (_ref1 = _ref.length) != null ? **_ref1 : _ref.length = false : void 0;**
};
if (y = getPageTitleFromMainContent($("#mainContent"))) {
y.css({
color: red
});
}
And it should be _ref : _ref.length = false : void 0;, not _ref**1** : _ref.length = false : void 0; .
http://jsfiddle.net/X8VjJ/1/
Thank you!
if it finds the #pageTitle in #mainContent, it should make it red
You can accomplish this with the much simpler:
$('#mainContent #pageTitle').css(color: 'red')
Since, if it doesn't find #pageTitle in #mainContent, it will try to change the css of an empty set of elements -- a no-op.
The code as you've presented it doesn't really make sense. ?. is unnecessary, as the jQuery selector will not return null or undefined if it doesn't match; it will return an empty set of elements. So it will always be returning length, which will always be a number, so the assignment will never execute, since it depends on length returning null or undefined. Which is good, since you probably don't want to set the length of the elements to false.
Finally, this isn't the ternary if statement. CoffeeScript's ternary if statement looks like this: if foo then bar else baz.
Not sure that code makes sense. You're effectively trying to assign TO the length property, unless length is defined. If it is defined, it simply returns the length property. Looks like the code and behaviour is correct, but your understanding of the existential operator and return values is wrong. If you want to return the found element you probably need to disconnect it from the length check.
Maybe something like:
getPageTitleFromMainContent = (mainContent) ->
arr = mainContent.find('#pageTitle')
if arr.length then arr else false
As Ian explained in his more elegant answer, you do not need to use the existential operator on arr (assuming jquery), since it will always be an array of elements (with zero length if not found).