If statement with only a number in Javascript - javascript

I found this function to put numbers in fractions and I am trying to figure out what everything means. There is one thing I can't figure out.
Here's the code:
function reduce(numerator,denominator) {
var gcd = function gcd (a,b) {
if (b) {
return gcd(b, a%b);
} else {
return a;
}
};
gcd = gcd(numerator,denominator);
return [numerator/gcd, denominator/gcd];
}
What does the if (b) mean. I know that if there is just the variable in the if statement it is checking if the variable is true or false. How would this apply to a number? When would this go to the else statement?

This is to do with how things get converted to Boolean, i.e. whether something is truthy or not
if (0 || NaN || undefined) { // these are "falsy"
// this never happens
} else if (1 /* or any other number*/ ){ // these are "truthy"
// this happens
}

If b is:
0
null
undefined
NaN
Or an empty string ""
it will be evaluated as false. Otherwise, it will be evaluated as true.

In javascript you can check if the variable is assigned by putting it in an if statement. If it has a value it will be true (well unless its value is false or 0). If it has no value or evaluates at null it will return false. Looks like they are verifying it has a value before passing it into the function.

Any expression in if statement will be implicitly converted to boolean before evaluated.
In the code you posted, it's usually used to check if a parameter is passed, in which case undefined is a falsy value and will be converted to false. AJPerez has given an answer on the falsy values (except for he forgot NaN).
function reduce(numerator,denominator){
var gcd = function gcd(a,b){
if (b) {
// if two arguments are passed, do something
return gcd(b, a%b);
}
else {
// only one argument passed, return it directly
return a;
}
};
gcd = gcd(numerator,denominator);
return [numerator/gcd, denominator/gcd];
}
However, this approach may be buggy if the argument you're checking is indeed passed by falsy.

Related

Default values for function parameters

These are the instructions to the script I have to write:
function longest(first, second) {
if (first.length >= second.length) {
return first;
} else {
return second;
}
Use the || operator to specify default values for first and second in
the function. If one or both parameters are not specified, the empty
string should be used as the default value.
Once you make your changes, you should be able to test the function as
follows:
console.log(longest('Alice')); // second is undefined - second defaults to the empty string
//Alice
console.log(longest()); // both first and second are undefined - both default to the empty string
//(an empty string)
console.log(longest('hi','hello'));
//hello
console.log(longest('hi', 'me'));
//hi
console.log(longest(''));
//(an empty string)
I don't even know where to begin. Can someone shed some light for me?
Try this:
function longest(first, second) {
var firstDefault = '';
var secondDefault = '';
first = typeof first !== 'undefined' ? first : firstDefault;
second = typeof second !== 'undefined' ? second : secondDefault;
if (first.length >= second.length) {
return first;
} else {
return second;
}
}
Default value
first = first || '';
Or, but that is not defined in the requirement
first = (typeof first !== 'undefined') ? first : '';
Apply this to both arguments
The issue with
function longest(first, second) {
if (first.length >= second.length) {
return first;
} else {
return second;
}
}
if you call it as longest('Alice') is that it spews out an error:
TypeError: Cannot read property 'length' of undefined
because second is undefined, and properties of undefined like .length can not be read.
undefined is actually a thing in Javascript rather than an automatic error like in many other languages. We'll come back to that soon...
The purpose is to get you to thinking about how to fix the function. If the function assigned a blank string in place of undefined, the blank string would have a length, 0, that could be read.
In Javascript the || operator can be used to assign default values to missing variables as follows:
function longest(first, second) {
var defaultValue = '';
var first = first || defaultValue;
var second = second || defaultValue;
if (first.length >= second.length) {
return first;
} else {
return second;
}
}
Now if either first or second is undefined, they will be replaced locally with the value of the defaultValue variable, which here is set to the empty string ''.
The empty string is not an undefined value, it is a string that contains no characters. It has a length, and that length is zero. Now the if statement will not fail when an undefined value is passed.
Now longest('Alice') yields 'Alice'
Bugs
Unfortunately the assignment as shown does not teach you enough about Javascript. It is probably worth knowing about a peculiar Javascript feature: any property whether it is called 'length' or something else can be read from existing objects that do not have that property. This may lead to undesired behavior. The result is a value called undefined, which is a value that things can be in Javascript.
When undefined is compared with a number, the result is always false. Mathematically that's normally impossible. We normally think that if x>1 is false, then x<1 must be true or x is 1. That kind of logic does not work for undefined.
When undefined is compared with undefined the result is also false, unless it is an equality test which is true.
Why does this matter? It relates to bugs in the longest() function above. Number inputs are one example. Strings representing numbers have a length but numbers do not have a length. Reading the length of a number yields undefined. And comparing undefined with a defined number is false. That means we can do this:
longest(1,100) returns 100 Correct.
but
longest(100,1) returns 1 OOPS.

what does && return in javascript expression

I was reading the javascipt code in some application and code was this
getTotalFees:function(){
return this.grid
&&this.grid.getStore().sum('fees');
}
Now i am confused what it will return.
IT looks to me like
return a&&b
won't it return true or false rather than b
Logical AND (&&):
expr1 && expr2 Returns expr1 if it can be converted to false; otherwise, returns expr2. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.
Source
So, basically:
If the first parameter is falsy, it returns that parameter. Else, it literally returns the second parameter.
In your case, this means that, if this.grid exists, it returns this.grid.getStore().sum('fees');
This is done to protect against calling a method on undefined property, witch would cause an error. So if this.grid is undefined, then undefined is returned.
In expressions if a && b when a equals to false (or in javascript it can be an expression like in Cerburs answer), then a is returned.
Similarly with || operator, the first from the left that equals to true (in javascript not 0, not undefined, not null, not NaN, and not false of course) is returned.
You misunderstand what && does. Let a and b be "entities". Then a && b does:
evaluate a
if a is falsy return a
if a is truthy evaluate b
return b
Example:
var f = function() {
console.log("test");
return 'foo';
}
> 0 && f()
0
> 1 && f()
test
"foo"
Note that in first case we didn't get console.log because f() was not evaluated because 0 is falsy. This property is important and actually
a && b != b && a
even though mathematically it should be the same (but it is not due to side-effects of evaluation).
Falsy values include: 0, false, "" (empty string), null, undefined,NaN (not a number type). I don't think there are any other possible values (someone correct me if I'm wrong). Every other object is truthy.
So in your case the code can be rewritten as:
if (this.grid) {
return this.grid.getStore().sum('fees');
} else {
return this.grid;
}
Ok, let's assume that this.grid.getStore().sum('fees') returns something, let's say "okay!".
now the return statement in your code is a convoluted way of saying :
if(this.grid)//this.grid is defined and doesn't evaluate as 'false'
return this.grid.getStore().sum('fees');
else
return this.grid;
if this hasn't got a grid, we return undefined, else we call gridStore... and return its own return.
It is a common way of avoiding "undefined has no method 'gridStore'"
the VERY important part is that, in a && f(), f() will NOT be called if 'a' evaluates to false. there are many things that evaluate to false, such as any undefined variable, null, empty strings... (note that strings that contain falsy things like "false" or "0000" are actually truthy). or even unreadable babble like function(){return null;}(); may evaluate as false.

Alert Based on Else/If In

very new to coding. I am testing to see if I can make an alert display based on a variable. I have the below code and I am trying to figure out why, in its current state, it is not displaying the "bye" alert. Here is the code:
document.getElementById("square").onclick=square;
function square(){
var test="a";
if (test="v") {
alert("hi");
}
else{
alert("bye");
}
}
You are using = which is an assignment operator.
Problem is in line
if (test="v") {
instead of =, use
if (test== "v") {
OR
if (test==="v") {
The identity (===) operator behaves identically to the equality (==) operator except no type conversion is done, and the types must be the same to be considered equal.
In your if statement, you need to write:
if (test === "v") {
alert("hi");
}
The way you have it right now, if (test="v") sets the variable test to the value v before evaluating the if statement. This is basically the same as doing this:
function square() {
test = "a";
test = "v";
if (test) {
alert("hi");
} else {
alert("bye");
}
}
Here, if(test) just asks if the variable test is not null, undefined, or an empty string ''. Because your variable does have a value "v", if(test) will always be true, so alert('hi') will always be run.
Because you are using = instead of == to compare variable test with value v.
The equal operator is for assignments: you use it to assign a value to a variable.
An assignment expression return the value you're assigning, so, in your case, v.
And since in javascript every non-empty string is coerced as true boolean value, your if branch is executed.
You should have used the == or === operator instead.
The == operator coerced two values to the same type, and return true if they are equal. So, for example,
2 == 1 + 1 => true
but also
"2" == 1 + 1 => true
The === operator is for strict equality. It doesn't coerce values type, and only return true if they are equal both in type and value. So, for example,
2 == 1 + 1 => true
but
"2" == 1 + 1 => false
because you're comparing a string with a number
To check a condition you should use a == b to check if value a is equal to value b
in your code you set the value of test variable to 'v'

Is there a simple way to toggle a javascript variable between true and false ?

I have this:
modalTogglePreview: function ($scope) {
if ($scope.modal.wmdPreview === true) {
$scope.modal.wmdPreview = false;
} else {
$scope.modal.wmdPreview = true;
}
}
Is there some way I could achieve the same but without the if statement ?
$scope.modal.wmdPreview = !$scope.modal.wmdPreview;
The unary ! operator interprets its argument as boolean, and returns the boolean complement. Note that this really isn't exactly the same as your code: yours only works if the variable is exactly true when it's tested. In my experience (for what that's worth), relying on variables used as flags in JavaScript to be real booleans is a little fragile. (There are counter-arguments however, so it's up to you.)
To explain further, the ! operator will interpret the values undefined, null, 0, NaN, false, and the empty string "" as being false. Any other value is true.
Aside from using the not operator as Pointy mentioned (which should be the preferred way), if you find yourself setting a boolean value inside an if...else statement, then you are likely doing something wrong.
The condition is already evaluated to a boolean value. So your if...else statement is equivalent to
$scope.modal.wmdPreview = $scope.modal.wmdPreview !== true;
Have a look at these examples:
var result;
if (cond) {
result = true;
}
else {
result = false;
}
This means, if the condition (cond) is true, set result to true. If cond is false, set result to false. The value we assign to result is exactly the value of cond. Hence the above is equivalent to writing
var result = cond;
Now, sometimes we use conditions that don't evaluate to a boolean. To convert any value to its boolean equivalent, you can apply the not operator twice:
var result = !!cond;
Similar for the other way round:
var result;
if (cond) {
result = false;
}
else {
result = true;
}
If cond is true, assign false to result. If cond is false, assign true to result. This is the same as in your situation. The value we assign to result is the opposite of the value of cond. As Pointy showed, we can use the not operator for this:
var result = !cond;
This works with every condition, but depending on the expression, it can make it harder to read. For example, !(x > 5) is not as obvious as x <= 5. So if you find yourself in such a situation, you can usually flip the comparison operator.

Javascript,doesn't show undefined number

I've created a variable with keys and values which looks like:
var e = new Array();
e[0] = "Bitte";
e[1] = "Danke";
Besides this I added a line in the variable which shows a text when the number is undefined.
e[NaN] = "Change Settings";
So when the variable e is NaN ("undefined"), I want that he doesn't displays the Number of the variable e in the input. I tried to achieve this as you can see, but it won't function.
if (neuezahl = NaN) {
document.getElementById("saveServer").value="";
} else {
document.getElementById("saveServer").value=""+neuezahl+"";
}
You have assigned neuzahl not compared it, aside that use the isNAN function:
if (isNAN(neuezahl))
{
document.getElementById("saveServer").value="";
}
else
{
document.getElementById("saveServer").value=""+neuezahl+"";
}
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/isNaN
NaN can't be compared directly (it's not even equal to itself NaN === NaN ==> false). Use isNaN() to detect NaN:
if (isNaN(neuezahl)) {...}
the condition in the if statement may not correct. Now you use "=" not "==", it is an assignment statement and the condition will always true. So if you want to check "neuezahl" is "NaN", function isNaN may help.
if (isNaN(neuezahl)){...}
else {}

Categories