I came across this line of code recently, and want to understand what it means and does, as my javascript-foo is not that hot :
if ((+!!config.template) + (+!!config.templateUrl) !== 1) {}
from what I can gather, it is checking to see if either option is set (so either template, or templateUrl must be set, not both or none)
so, if config.template was set,
+config.template would not work (template is not a number)
!config.template would return false (-1)
!!config.template would return true (0)
+!!config.template would therefore return 1
if config.template was not set,
!config.template would return true (0)
!!config.template would return false (-1)
+!!config.template would therefore return 0
if then you were to apply the same to config.templateUrl , you would end up with 1 if set, 0 if not
So the final test is to see if the sum of config.template and config.templateUrl is 1 (ie one or the other is set)
Is this valid reasoning ?
The bool value is being cast to a Number by prepending it with +.
!! in the code above is checking for existence of the property template on config. If there is no template found !! would usually return false, however by prepending +, it returns 0. Both +!! statements return numbers, which when they're added together will either be 0 or 1.
The final check will return true if both or none were set / true (!== 1)
Related
I'm pretty new to Javascript and React, so please bear with me.
I have a component in my app, that is taking a timespan from the user, but now I want to calculate the price the user would have to pay, depending on their input. I figured that it would probably be the easiest way to use an if loop but something is very off with that and I am a little stuck.
Is my attempt okay in general or does it need a separate function that I have to call in order to do what I want to do?
onConfirm(hour, minute) {
this.setState({ time: `Dauer: ${hour}:${minute}` });
this.setState(if((hour) < 4){return price = `Preis: (${hour}* 1.5) €`;}
else {return price= 'Preis: 5.50 €';} );
this.TimePicker.close();
}
Within an object literal, you can't use statements, only expressions. if is a statement.
If you want to do that either/or logic in an expression, you use the conditional operator (? :), like this:
onConfirm(hour, minute) {
this.setState({
time: `Dauer: ${hour}:${minute}`,
price: hour < 4 ? `Preis: (${hour}* 1.5) €` : 'Preis: 5.50 €'
});
this.TimePicker.close();
}
The conditional operator expression in the above is:
hour < 4 ? `Preis: (${hour}* 1.5) €` : 'Preis: 5.50 €'
It's a ternary operator (an operator accepting three operands):
The condition to test (hour < 4)
The expression to evaluate if the condition is truthy¹ (`Preis: (${hour}* 1.5) €`)
The expression to evaluate if the condition is falsy¹ ('Preis: 5.50 €')
Also note you had a closing ' on a template literal (needed a backtick instead).
¹ "truthy" and "falsy" - JavaScript implicitly converts (or coerces) values. When you use a value as a test, such as in an if or a conditional operator, JavaScript converts the value you provide to a boolean value (true or false). Values that convert to true are called "truthy" values, ones that convert to false are called "falsy." The falsy values are NaN, null, undefined, 0, "", and of course false (on browsers, document.all is also falsy for various reasons I explain in my book). All other values are truthy.
I was wondering, say I had some thing like the following:
console.log(element.find('div').eq(3).text().indexOf('whatever'));
bearing in mind that element is defined and the console is logging a value of 32 (or anything that isn't -1) what would be the best way of converting the result into a Boolean so my console.log either outputs true or false
Thanks in advance.
The answer above will work, however if you are as nerdy as I, you will far prefer this:
console.log(~element.find('div').eq(3).text().indexOf('whatever'));
The obscure '~' operator in javascript performs the operation "value * -1 - 1", e.g. ~-2 === 1. The only use case I have ever had for this is in converting the "not found" -1 from ".indexOf()" into "0" (a falsey value in javascript), follow through and see it will convert an index found at position "0" to "-1", a truthy value.
tldr:
~[1,2,3].indexOf(0) // => 0
!!~[1,2,3].indexOf(0) // => false
~[1,2,3].indexOf(1) // => -1
!!~[1,2,3].indexOf(1) // => true
console.log(element.find('div').eq(3).text().indexOf('whatever') > -1);
I'm trying to find out if a string exists like so:
var test1 = '{"packageId":"1","machineId":"1","operationType":"Download"},{"packageId":"2","machineId":"2","operationType":"Download"}';
alert("found: " + test1.indexOf('{"packageId":"1","machineId":"1","operationType":"Download"}', 0));
However, the result is always 0.
what gives?
Just in case this isn't a joke...
String.prototype.indexOf returns the occurence of a matching string within a target string, since you just look for the very first occurence of that line, it correctly returns zero.
If you modify your search-string (for example with some random letters), you will get -1 as result since it will not get found.
There is a practice using the binary not operator, to pretty much bring the result from .indexOf() down to a boolean expression. This would look like
var res = test1.indexOf('{"packageId":"1","machineId":"1","operationType":"Download"}');
if( ~res ) {
// we have a match
} else {
// no match at all
}
Without going into great detail, the not-operator will negate each bit from a byte, also the extra bit which is used to determine if the value is positive or negative. So, since in ECMAscript only very few values are evaluated to falsy values, negative values will evaluate to true.
To really have a boolean result, it would look like
if( !!~res ) { }
which again is not really neccessary in this case.
The far more often used practice to get the "right" result using .indexOf() (same goes for Arrays), is to check if the result is greater than -1
if( res > -1 ) { }
ya its correct indexOf will return starting index of the string you mention, thats y its gives 0. If string is not exist it return -1
Some sample example
var sample= "welcome to javascript";
alert ( sample.indexOf("welcome",0)); // return 0
alert ( sample.indexOf("come",0)); // return 3
alert ( sample.indexOf("came",0)); // return -1
alert ( sample.indexOf("javascript",0)); // return 11
Match :
if(sample.indexOf("welcome",0)>-1)
alert("match");
else
alert("Not match")l
Before anyone jumps in to answer and bash me for asking a silly question; I'm aware of what the not operator does, at least in other languages it should invert a result from true to false and vice versa. The thing I'm stuck on is the strange behavior I get from time to time. I.e. I had this in my code. It's not doing what I expect it to do.
_checkOnOff: function(inst) {
return (!$.suggestBox.onOff || !$.suggestBox._get(inst, 'onOff')) ? false : true;
},
The actual values for the 'onOff' variables that I'm dealing with here are 0 and 1. I'm assuming that the '!' operator will reverse them.
However I couldn't get it to work until I changed the function to explicitly state '== 0' like so...
_checkOnOff: function(inst) {
return ($.suggestBox.onOff == 0 || $.suggestBox._get(inst, 'onOff') == 0) ? false : true;
},
Edit: Added info Both $.suggestBox.onOff and $.suggestBox._get(inst, 'onOff') will be either 0 or 1.
My question is why didn't !$.suggestBox.onOff produce true when $.suggestBox.onOff was equal to 0? Is Javascript ! equivalant to the bitwise operator?
Edit: Second attempt
I tried using '!!' like was suggested (to get a bool) and found nothing changed. Here is the code and outputs:
console.log('val: ' + $.suggestBox.onOff); // outputs: 0
console.log('! : ' + !$.suggestBox.onOff); // outputs: false
console.log('!! : ' + !!$.suggestBox.onOff); //outputs: true
console.log('!!! : ' + !!!$.suggestBox.onOff); //outputs: false
The output doesn't change if $.suggestBox.onOff is 1 or 0!!! it's still false, true, false. What is going on?!
Edit: Third attempt I found out that it has something to do with my variable. I don't know how, but it has to do with the way that it has been set. Ok, prepare yourselves, what I'm about to tell you, may very well blow your mind and change the way you type on the keyboard. It's that incredible:
//this.onOff = 0;
console.log('this.onOff: ' + this.onOff); //output: 0
console.log('! : ' + ! this.onOff); //output: false
console.log('!! : ' + !! this.onOff); //output: true
If I uncomment out the 'this.onOff = 0', thereby explicitly assigning this.onOff to a literal, it changes the output to:
0
true
false
I just found out why. I will write it down in the answer section. Small clue is that it's the way the variable $.suggestBox.onOff was set.
It seems that $.suggestBox.onOff is set with "0" as a string, which in JavaScript is always truthy.
Since "0" is truthy and 0 is falsy, you'd expect 0 == "0" to be false, but it's not.
Try the following in your console:
!! "0"; // true
!! 0; // false
0 == "0"; // true
Weird? Yes. Welcome to the awkward world of JavaScript!
To get around this issue, you should either have $.suggestBox.onOff be an actual number, or convert it on the fly:
_checkOnOff: function(inst) {
return !! ( +$.suggestBox.onOff && +$.suggestBox._get(inst, 'onOff') );
}
Update: Since you pointed out in the comments that you're setting it by a text value, use this when setting it so that it's always set as a number:
$.suggestBox.onOff = +$(this).val();
I think you're confused, because you're negating a string, not a number. Strings are a bit different and handled a bit funny when it comes to their evaluation as a boolean.
!0
is true, as expected.
!"0"
is false... so, the question, is "0" truthy?
I wish I had a better source (sitepoint isn't bad, but it's not as authoritative as a w3 document), but, according to http://www.sitepoint.com/javascript-truthy-falsy/
The following values are always falsy:
false
0 (zero)
"" (empty string)
null
undefined
NaN (a special Number value meaning Not-a-Number!)
All other values are truthy, including
"0" (zero in quotes), "false" (false in quotes), empty functions,
empty arrays, and empty objects.
So, what you are seeing is indeed expected.
I am returning cookies through a Chrome Extension - one of the cookies.name is use_hitbox - so naturally I want to do:
if (cookie.name.indexOf("use_hitbox") > 0) {
alert("FOUND HITBOX COOKIE");
}
The Issue is:
cookie.name.indexOf("use") returns true
cookie.name.indexOf("hitbox") returns true
cookie.name.indexOf("use_hitbox") returns false
Any ideas?
Disclaimer:
This is for use on MY site, nothing malicious...!
EDIT: Cool, this works - but the underlying issue was Chrome Caching my Extensions file
indexOf() will return 0 if the match is at the beginning of the string. -1 indicates no match so try:
if (cookie.name.indexOf("use_hitbox") > -1)
Rather than parsing the returned index as boolean (which as pointed out, will mean an index of 0 parses as False), compare result != -1, which is the return value if the substring is not found.