I'm trying to understand the below block of syntax (taken from angular docs to represent the use of angular noop as an 'empty' function)
function foo(callback) {
var result = calculateResult();
(callback || angular.noop)(result);
}
I don't understand the '||' syntax. I tried looking it up but had trouble searching and wasn't really sure what to search.
Thinking of it as 'OR' syntax, it would mean to me if a function was assigned to the callback or if the function was assigned to angular noop would equal true and then a function is being called on true. But obviously that's wrong
Apologies in advance for the newbishness of the question.
- EDIT -
To clarify further, I'm aware of what it does guessing from the example. However, I'm trying to figure out what javascripts rule say that would cause the return statement for (callback1 || callback2) to return a function object instead of a boolean (as implied by the fact that in the example you can call the return of the sub-expression).
This bit
(callback || angular.noop)(result);
is short for:
if (callback) {
callback(result);
} else {
angular.noop(result);
}
It takes advantage of the fact that || is lazily executed. The search term you're looking for is lazy evaluation. To explain the "why" on how this works, we can take a look at the ECMAScript specification, specifically 11.11 Binary Logical Operators,
The value produced by a && or || operator is not necessarily of type Boolean. The value produced will always be the value of one of the two operand expressions. Note that this doesn't mean that you can't depend on an expression such as:
if (a || b) // <-- logical expression will evaluate to the value of a or b, NOT true or false
because JavaScript evaluates boolean values as truthy or falsy, formally defined as the operation ToBoolean() in the ECMAScript specification.
From 9.2 ToBoolean
The abstract operation ToBoolean converts its argument to a value of type Boolean according to Table 11:
Argument
Type Result
Undefined false
Null false
Boolean The result equals the input argument (no conversion).
Number The result is false if the argument is +0, −0, or NaN;
otherwise the result is true.
String The result is false if the argument is the empty String
(its length is zero); otherwise the result is true.
Object True
Basically the statement
(callback || angular.noop)(result);
Can be read as:
Call the function callback or angular.noop with the argument of result
If callback is not defined the OR (||) will be evaluated to call the angular.noop function passing the variable result to the function.
The angular.noop() function is a function that does nothing. More read here https://docs.angularjs.org/api/ng/function/angular.noop
Related
I'm trying to learn JavaScript by going through some code in an application and I keep seeing !variable in if conditions. For example:
if (!variable.onsubmit || (variable.onsubmit() != false)) {
What is it? Some kind of test if the variable is empty?
! is the logical not operator in JavaScript.
Formally
!expression is read as:
Take expression and evaluate it. In your case that's variable.onsubmit
Case the result of that evaluation and convert it to a boolean. In your case since onsubmit is likely a function, it means - if the function is null or undefined - return false, otherwise return true.
If that evaluation is true, return false. Otherwise return true.
In your case
In your case !variable.onsubmit means return true if there isn't a function defined (and thus is falsy), otherwise return false (since there is a function defined).
Simply put - !variable means take the truth value of variable and negate it.
Thus, if (!variable) { will enter the if clause if variable is false (or coerces to false)
In total
if (!variable.onsubmit || (variable.onsubmit() != false)) {
Means - check if variable.onsubmit is defined and truthy (thus true), then it checks if calling onsubmit returns a result that coerces to true. In a short line it checks if there is no onsubmit or it returns true.
Next time, how do I find this myself?
MDN has a list of operators here.
The language specification specifies such operators, though being the official specification it does contain some jargon which might be hard to understand.
It is a negation operator used for truth tests on a variable.
var myVariable = 1;
if ( ! myVariable )
{
// myVariable evaluates as false
}
if ( myVariable )
{
// myVariable evaluates as true
}
The selected answer already answers the question. One thing to add in this is that ! operator can be used in a rather interesting fashion.
obj = {}
if (!!obj) {console.log('works')} // !!obj = true
obj = undefined
if (!!obj) {console.log('does not work')} // !!obj = false
So double !! will change any expression to a boolean value with no exceptions.
This has a very peculiar use case in some cases.
Lets say there is a function that returns either true or false and nothing else. In that case one could just change return returnValue to return !!returnValue for extra caution (although not need in most of the cases)
Conversely, if a function only accepts true or false and nothing else, one could just call the function as functionA(!!parameter) instead of functionA(parameter), which again is not needed in most of the cases, but could ensure extra security
! is a logic reversal operator, if something was true it will change it to false, if something is false, it will change to true.
example, we know that empty string or 0 in boolean is false.
let a = Boolean("")
console.log(a) // shows false, because empty string in boolean is false
console.log(!a) // shows true, because logic is reversed
easier example:
let a = 5
let b = 1
let c = a > b
console.log(c) // shows true, since a,5 is bigger than b,1
console.log(!c) // shows false, since logic is now reversed
This question already has answers here:
What is "x && foo()"?
(5 answers)
Closed 8 years ago.
I'm reading the source code for the Twitter Bootstrap Tabs Plugin and there's a line that appears to be short hand for something, but I don't understand what it is. Here's a snippet from the source (version 3.0.0):
Tab.prototype.activate = function (element, container, callback) {
var $active = container.find('> .active')
var transition = callback
&& $.support.transition
&& $active.hasClass('fade')
function next() {
$active
.removeClass('active')
.find('> .dropdown-menu > .active')
.removeClass('active')
// some code removed for conciseness
callback && callback()
}
The line in question is this: callback && callback().
I've never seen a function or variable name just typed out like that and then a function being called after the && operator.
I'm guessing this is short hand. What is it and what is it meant to do? And how does it work?
It is shorthand for
if (callback)
{
callback();
}
Basically if the first part is null (or undefined) which both equate to false, the && (logical and) fails and it does nothing.
If the callback is defined, the first part of the && is true, so it evaluates the second part (in this case calling the method).
This is known as short-circuiting as an initial false on the left hand side of the logical AND operator means it does not attempt to evaluated the second part of the expression on the right hand side (as it has already failed the test for "is everything true"). Note: not all languages implement short circuiting in logical AND expressions (VB does not from memory), but javascript is one of the sensible ones! :)
For those that care about the finer points of undefined vs null vs 0 checks:
http://www.sitepoint.com/javascript-truthy-falsy/
*Disclaimer: The code example was intentionally simple and performed by a trained stunt-coder. Please do not attempt this at home. It is dangerous and may lead to down-votes :)
The && operator works like this:
a && b
Evaluate a
If a is falsy, return a
Return the result of Evaluate b
So, the line your mentioned is equivalent to this:
if the value of callback is truthy, call callback as a function
You can easily trip up this code if you supply callback as non-zero number, non-empty string or object, but if you supply a function or nothing (that's what the author of the code expects), then it will work properly and only call the callback if it is provided.
EDIT:
Truthy/Falsy explained in short:
Falsy values: undefined, null, false, 0, '', NaN
Truthy values: everything else
Longer explanation: http://www.sitepoint.com/javascript-truthy-falsy/
It will check if callback exists and if it does then it will run it. The reason is the && operator which will short circuit in the case that the first argument is false. So if callback does not exist it will not check the second half
It's the same as:
if (typeof callback != "undefined"){
callback();
}
All objects are considered to be true.
Strings are considered to be false if they are empty.
null and undefined are considered to be false.
A Number is false if it is zero.
http://msdn.microsoft.com/en-us/library/ie/719e8e30%28v=vs.94%29.aspx
and in logical && if first one is false so is the entire statement. hence if there is no callback (false), then next part of the && won't execute (which is the callback() function calling)!
What does if(a) exactly check in javascript? Can it check undefined? Can it check null? Can it check an empty string?
When do we need to use typeof a == 'undefined' or it could be covered by if(a)?
if evaluates a in a boolean context and uses the result to determine which code branch to execute. undefined, null and the empty string all evaluate to false in a boolean context.
typeof a === "undefined" is useful to check if the name a is defined (e.g. if a variable with that name exists in the current scope). Without this construct, accessing a directly would throw an exception if it is not defined.
Taken from the ECMAscript language specification, the if-Statement works as the following:
12.5 The if Statement
The production IfStatement : if ( Expression ) Statement is evaluated as follows:
Let exprRef be the result of evaluating Expression.
If ToBoolean(GetValue(exprRef)) is false, return (normal, empty, empty).
Return the result of evaluating Statement.
Means, in such cases, it would try a toBoolean conversion which acts like this:
Table 11 - ToBoolean Conversions
Undefined: false
Null: false
Boolean: The result equals the input argument (no conversion).
Number: The result is false if the argument is +0, -0, or NaN; otherwise the result is true.
String: The result is false if the argument is the empty String (its length is zero);
otherwise the result is true.
Object: true
It checks for a value not being false-ish, i. e. false, 0, undefined and null or an empty string. typeof a == 'undefined' is useful when you are curious if a value is undefined or not, since if (a) can't make the distinction between the false-ish values.
The conditional statement will only check for 'true' or 'false'.
in case of undefined the condition is not satisfied and control does not go into the loop.
typeof returns the type of operand. for details you may want to see this link
following values are considered as false in javascript conditions: false, null, undefined,'', 0, NaN
the answer by h2co3 is actually almost correct, you can not check for undefined variables in an if without typeof as this will cause a script error.
if you do this:
<script>
if (a) alert('hello');
</script>
you will get a script error and the if will not be evaluated (the result is the same in the sense that alert is not shown, but that's because the thread execution ended due to the script error.)
if you want to make sure a is defined you need to use the typeof test.
What does this JS expression mean? What are we returning?
return dihy(year) in {353:1, 383:1};
This is a return statement that causes the containing function to return a Boolean value.
It calls the function dihy() with the value of the variable year as its argument.
It checks whether the return value is either 353 or 383 (the names of the properties that exist in the object literal). It does not matter what value the property has; it just needs to exist within the object. (That is, 1 is just an arbitrary value.)
If so, the function returns true, otherwise false.
JavaScript programmers sometimes use this approach because it is shorter than checking against each value individually, and it is easy to programmatically add new values to check against:
var foo = {353: 1, 383: 1};
function bar(year) {
return year in foo;
}
alert(bar(1955)); // false
foo[1955] = 1;
alert(bar(1955)); // true
You may want to look at the MDC documentation for the in operator.
It will be true if the call to the function dihy with the argument year is a key in the object {353:1, 383:1} and false otherwise.
It could be rewritten like this for example:
var result = dihy(year);
return result == 353 || result == 383;
This is an expression:
dihy(year) in {353:1, 383:1}
The dihy(year) function call presumably returns a Number value. If that value is either 353 or 383, the expression will evaluate to true, otherwise to false.
Note that your code is not an expression, but a statement, the return statement:
return expression;
So, the return statement will either return true or false.
Returns true or false, depending is the result that dihy() returns 353 or 383 (true for those two, anything else is false).
And it means exactly that... is the result of this function contained in this data collection...
There is no reason to use an object here, i.e. {353: 1, 383: 1}. In fact, the values of 1 are confusing and can make the uninitiated think that the value of 1 is being returned when it is not and is purely arbitrary.
The following is equivalent:
dihy(year) in [353, 383]
In the below code how does passing bar as
function (n) { return n; }
to foo evaluate to true in the if block?
function foo(bar) {
if (bar) {
// true
} else {
// false
}
}
This has me puzzled so any help is much appreciated.
If bar is bound to an anonymous function, then it is an object. Objects are 'truthy' in JavaScript.
The only values in JavaScript that are 'falsy' are:
false
null
undefined
'' (empty string)
0 (zero as a number)
NaN
Everything else is 'truthy', including function objects.
If you meant to call the anonymous function, you'd do if (bar(5)) which would call your anonymous function with the argument 5. Then your anonymous function would return n (which is 5 in this case). As 5 is not a falsy object, this would go to the true branch as well. Doing if (bar(0)) would got to the else branch, because 0 is falsy.
Anything not null, 0, false, empty string or undefined is going to evaluate to true in an if(something) statement, this is just how weak-typing in JavaScript works.
If you want more specificity you may want to look at the typeof operator to check for the type you're expecting, or use a another stronger check like this:
if(bar === true) {
Using === checks for both value and type equivalence.
You could use typeof() if you want to know what type it returns
It always return true, because bar is not null. if an expression within an if statement is not a logic expression (e.g. if(x <7)) then performs a check for null. If it is null it returns false, otherwise true.
In your example you have defined bar as the function {returns n;} so that is why your if statement is evaluating to true.
If bar returns a bool (true or false) then you need to call the function and get the result, rather than passing a reference to the function - this is done using parentheses:
var exampleA = bar(false); // executes function bar and returns the result (false) in exampleA
var exampleB = bar; // stores a reference to the function bar in variable exampleB