I am going through a book about HTML5 and there are two lines of code I cannot quite understand
var mp3Support,oggSupport;
var audio = document.createElement('audio');
if(audio.canPlayType) {
mp3Support = "" != audio.canPlayType('audio/mp3');
}
So, first you create an audio element and check if canPlayType method can be used?
Then, the code inside the if statement is some kind of ternary operation?
The audio.canPlayType('audio/mp3') outputs 'probably' and mp3Support is set to '' but after that line mp3Support outputs true. Any tips would be much appreciated.
So, first you create an audio element
Yes
and check if canPlayType method can be used?
The check is to see if canPlayType is a true value, but that amounts to the same thing in practical terms.
Then, the code inside the if statement is some kind of ternary operation?
No.
audio.canPlayType('audio/mp3') can return a number of values, one of which is an empty string.
"" != audio.canPlayType('audio/mp3'); tests to see if it not an empty string (and evaluates as true or false)
mp3Support = then is just assigned that true or false
It could be more clearly written as:
mp3Support = ("" != audio.canPlayType('audio/mp3'));
mp3Support = "" != audio.canPlayType('audio/mp3');
This combines a variable initialization with boolean expression.
in other way:
if(audio.canPlayType('audio/mp3')!="")
{
mp3Support=true;
}
else
{
mp3Support=false;
}
Related
Context : I am trying to reduce my code for a reactjs project that I am working on using expo. In one of my if else statements, one boolean variable's value is changed based on whether any of multiple other boolean variables are false. I wanted to make this much more optimized and remove unnecessary code since its for a mobile app.
My question is : Is there a way to make an if statement shorter while checking whether a variable is false?
if(variable){}
is the same as
if(variable === true){}
Is there a way like this for false as well? Maybe something like
if(!variable){}
I'm not exactly sure and couldn't find any method similar to what I showed above anywhere online (yet).
Example of the code I have right now :
var example = false
if(var1 === false || var2 === false || var3 === false || var4 == false){
example = true
}
if any of the variables are false (hence the ||), it should switch over
Thanks in advance!
This should be exactly the same as long as varN is already a boolean:
var example = false
if(var1 && var2 && var3 && var4){
example = true
}
But it must by said that premature optimizations rarely lead to improvements. Most often the interpreter already takes care of any optimizations like that. And the speed-increas one can get by changing simple comparisons are close to none.
So I would rather keep it in the most readable state than the most optimized.
Here's a shorter version:
var example = false
if (!(var1 && var2 && var3 && var4)) {
example = true
}
I wouldn't call this "optimization" and I don't think there's anything wrong with your code to begin with.
Edited:
you can use some()
if([var1,var2,var3,var4].some((item)=> item === false) ){
example = true
}
This question already has answers here:
Empty arrays seem to equal true and false at the same time
(10 answers)
Closed 4 years ago.
I was trying out a code snippet and the results are different for an empty array check inside a console.log statement and in a conditional statement.
Help/Thoughts on why this is different?
Thanks in advance!
//Output: true
if([]) {
console.log(true)
} else{
console.log(false)
}
//Output: false
console.log([] == true)
You seem to be running into a known JavaScript quirk.
"[] is truthy, but not true"
The problem isn't where you are doing the evaluations, but rather that the two evaluations which seem identical are actually different.
See
https://github.com/denysdovhan/wtfjs#-is-truthy-but-not-true
My assumption is that the if/else block, in part of its "truthful" test is checking if something exists (not just if it is true or not) -- wherein the straight console print is comparing the value of the empty array against a boolean (which would be false)
let test = 'apple';
if( test ){
console.log( 'if/else: ' + true );
}else{
console.log( 'if/else: ' + false );
}
console.log( 'log: ' + ( test == true ) );
The two snippets are actually doing different things, hence the different results.
The first, with [] as the condition of the if statement, coerces the array to a Boolean value. (if, naturally enough, only works on Booleans, and JS will happily convert the given value if it isn't already Boolean.) This produces true - all objects in JS are "truthy", which includes all arrays.
For the second snippet, you are using the "loose equality" operator == - for which the JS specification provides a set of rules for how to convert the values into other types, eventually reaching a straightforward comparison between two values of the same type. You might want, or hope, that comparing a non-Boolean to true or false in this situation coerced the non-Boolean to Boolean - but this isn't what happens. What the specification says is that first the Boolean is coerced to number value - resulting in 1 for true (and 0 for false). So it reduces to [] == 1 - which will go through a few more conversions before resulting in a false result.
The key point is that no conversion to Boolean happens in the second case. If you think this is stupid, you're probably right. This is a bit of a gotcha, and one of the reasons many guides tell you never to use == in JS. I don't actually agree with that advice in general (and hate linters telling me to always use === in any circumstances) - but you do have to be aware of some dangers. And using == to compare a value to true or false is something to always avoid.
Luckily, if you want to test if x is truthy or falsy, you have a very short and understandable way to do it - the one you used in the first snippet here: if (x)
[edit] So my original answer was confusing as heck, and there are some incongruencies in the many answers you find on this subject all over the internet; so, let me try this again:
Part 1: Why they are Different
if([]) and if([] == true) are not the same operation. If you see the below example, you will get the same result when doing the same operation.
//Output: false
if([] == true) {
console.log(true);
} else{
console.log(false);
}
//Output: false
console.log([] == true);
Part 2: Why it matters AKA: the confusing bits
In JS, the following is a common expression used to see if an object/variable exists:
var foo = "Hello World";
if (foo) ...
From a design perspective, this test is not important to see if foo is equal to true or false, it is a test to see if the program can find the object or variable foo. If it finds foo, then it executes the results in the "then" condition, otherwise you get the "else" condition. So, in this case, it will convert foo to either false for does not exist, or true for does exist. So in this case the string is reduced to a boolean.
In contrast:
var foo = "Hello World";
if (foo == true) ...
Is typically trying to find out if the value of foo actually equals true. In this case, you are comparing the value of foo "Hello World" to a boolean, so in this case, "Hello World" does not equal true.
Just like foo, [] can be evaluated more than one way. An empty array is still an object; so, in the first case, it coerces to true because it wants to know if [] can be found; however, [] also equals ['']. So now picture this:
if (['bar'] == 'bar') ...
In this case, JS will not look at ['bar'] to see if it is there, but as an object containing a single value which it can convert to the string, 'bar'.
So:
if([]); // is true because it is an object test that evaluates as (1 === 1)
and
if([] == true) // is false because it is a string test that evaluates as ('' == 1) to (0 === 1)
I see in the code I am working on often the following code style;
var1 == true && (var2 = true)
After some testing I figured it comes down to:
if (var1 == true) {
var2 = true;
}
Is this correct, or is there more to it? And why would anyone use this since the readability just dramatically reduces, since your assume at first glance it is just a check on two variables. So you really have to start looking at single or double equal sings and where the parentheses are, which just kinda, you know.. Just curious here..
Yes, this is equivalent. As far as I know, it is called short-circuit evaluation, describing the fact that the interpreter will return false for the whole boolean expression as soon as one of its parts is falsy.
Indeed, in your example it DOES reduce readability. But I think of it as just another tool in your toolbox you may use when you feel it could be useful. Consider the following:
return user && user.name;
This is one example when I tend to use it. In this case, I think it's actually more readable than
if (user) {
return user.name;
} else {
return undefined; // or null or something alike
}
UPDATE
I want to give you another example when I consider this kinds of constructs useful. Think of ES6 arrow functions like user => user.name. It does not need {} to open a body since it just has one line. If you wish to log something to the console (for debugging), you would end up having
user => {
console.log(user); // or something alike
return user.name;
}
You might as well use the shorter variant
user => console.log(user) || user.name
since console.log returns undefined after logging into the console, hence user.name is returned.
Yes, as you've mentioned there's more to it.
the first part var1 == true checks whether ther result is true or false.
if the condition is false the code after it doesn't get checked or evaluated and thus var2 doesn't get set to true.
But if the first part of the condition var1 == true is true which obviously is true, the second part of the conditional statement the part after && is checked.
now the second part of the condition is an operation it sets (var2 = true) which is kind of a truthy operation.
we could edit your code a little bit to help you understand the operation more clearly:
if( var1 === true && (var2 = true)){console.log('good');}
I hope this helps
Here is jquery code in rails app. The purpose of the code is to eval the value of #rfq_need_report and show the #rfq_report_language if need_report is true or hide if false:
$(document).ready(function() {
var rpt = $('#rfq_need_report').val();
alert(rpt);
if (rpt) {
alert(rpt);
$('#rfq_report_language').show();
alert('show');
} else {
$('#rfq_report_language').hide();
alert(rpt);
alert('hide');
}
}); // end ready
The alert here is just for debug. The rpt is false, however alert('show') gets executed. It seems that the if loop is taking false and decided to execute the loop for true. Sometime If loop is working and sometime it does not. What could cause this strange behavior? Thanks.
In HTML the value field of any input like value="something" is always evaluated as a string. My guess is that in javascript you either set that value to true or false but it is in fact set as "true" or "false" as strings. You could try what was answered on this topic : How can I convert a string to boolean in JavaScript?
rpt could be a string, therefore converting it into a boolean will help:
if(rpt === "false") { rpt = false; } else { rpt = true; }
I have to assume that $('#rfq_need_report').val() is not passing back an actual boolean value, but something that JavaScript considers 'truthy', which is why your if statement executes the truth clause.
There are two quick methods (that I use) to convert 'truthy' values to an actual boolean:
1: var bool = !!truthy;
2: var bool = truthy === 'true'
I use the second when expecting a string value, and the first when not expecting a string.
The first example may need an explanation, so...
The first ! "nots" the truthy value to an actual boolean, albeit the opposite of what I wanted, the second "nots" it right back to where it should be.
For more examples of truthy vs falsy, simply pop javascript truthy falsy into your favorite search engine and start reading. My personal quick reference is: Truthy and falsy in JavaScript
Today one of my friends said:
if (typeof isoft == "undefined") var isoft = new Object();
is such kind of code is writted by a freshman and writes
if(!isoft) var isoft = new Object();
I originally consider there must be some difference. But I can't find the difference. Is
there any? Or are the two examples the same?
Thanks.
See the question Javascript, check to see if a variable is an object but note that the accepted answer by Tom Ritter appears to be incomplete, check the comment on his answer. See also the community answer by Rob.
In the example involving regular objects that you provided there is little difference. However, another typical pattern can be:
var radioButtons = document.forms['formName'].elements['radioButtonName'];
if ('undefined' === typeof radioButtons.length) {
radioButtons = [ radioButtons ];
}
for (var i = 0; i < radioButtons.length; i++) {
// ...
}
If you used if (!radioButtons.length) it would evaluate true when no radio buttons were found (radioButtons.length is 0) and create an array of a single (non-existent) radio button. The same problem can arise if you choose to handle the radio buttons using:
if ('undefined' === typeof radioButtons.length) {
// there is only one
} else {
// there are many or none
}
There are other examples involving empty strings where if (!variable) is probably not recommended and it is better to test against typeof undefined or explicitly test against null.
If isoft should hold a reference to an object, both do the same. A !isoft is true for all false values, but a object can't be a false value.
In your particular example there's no significant difference, since you're evaluating Object instance, and objects are converted to Boolean true when cast to Boolean, while undefined and null are evaluated as Boolean false.
But take this for an example:
function alertSomething(something) {
//say you wanna show alert only if something is defined.
//but you do not know if something is going to be an object or
//a string or a number, so you cannot just do
//if (!something) return;
//you have to check if something is defined
if (typeof something=='undefined') return;
alert(something);
}
I like to take shortcuts and save typing wherever I can, sure, but you have to know when to take a shortcuts, and when not to ;)