I've found unknown for me code construction on JQuery site. After some formatting it looks like:
function (a,c) {
c==null && (c=a,a=null);
return arguments.length>0
? this.bind(b,a,c)
: this.trigger(b)
}
What does the first line of the function mean? Is it any trick or standard JS code construction?
It's a trick that uses boolean short-circuit evaluation to only do the second half if the first evaluates to true. Perl has this commonly:
<something> or die
where if the first statement failed, the program ends.
Read it as
if (c == null) { c = a; a = null; }
That's an ugly way to write
if(c==null) {
c = a;
a = null;
}
This utilizes the fact, that the second part of boolean && will be executed if, and only if the first part evaluates to true.
The expression uses two JavaScript features :
short circuit evaluation of boolean operators: in statement context, a && (b); is equivalent to if (a) (b);
the comma operator to group assignment expressions: in statement context, a=b,b=c; is equivalent to { a=b; b=c }
As a result the expression is equivalent to:
if (c == null) {
c = a
a = null
}
Related
I'm writing a script to be executed when my body element hasn't got any of the following classes:
a OR b OR c AND d
I tried this, but it doesn't seem to do the trick:
if ((!$('body').hasClass('a')) || (!$('body').hasClass('b')) || ((!($('body').hasClass('c')) && (!$('body').hasClass('d'))))) {
}
UPDATE
This seems to work:
if (!($('body').hasClass('a') || $('body').hasClass('b') || $('body').hasClass('c') && $('body').hasClass('d'))) {
}
use
$(function(){
if ((!$('body').hasClass('a')) || (!$('body').hasClass('b')) || !($('body').hasClass('c') && $('body').hasClass('d'))) {
}
});
You are looking for a body that doesnt have any of the classes, so you need to use &&. Heres what happens:
if(hasclass(a) || hasclass(b)) = if(true OR false) = if(true)
Above the OR operator || means that once it hits a true evaluation, it will execute your if-block.
if(hasclass(a) && hasclass(b)) = if(true AND false) = if(false)
Here the AND operator && means that once you hit a false evaluation, you block won't be executed.
You want the last thing to happen, since you want it to have neither of the classes. Learn how to play with these operators as they can be very confusing. As long as you remember that the AND operator will execute only if all statements are true and the OR operator will only execute if one of the statements is true. Nested operators work the same, so if((a = b && b = c) || (a = c)) will execute if a,b and c are the same OR when a and c are the same, but not when a and b are the same or a and c are the same.
More on expression and operators (specifically Bitwise and a must read): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise_operators
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What does this construct (x = x || y) mean?
I've seen this code here. And some similar code on other places that I can't recall.
time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
type = type || "fx";
What does it mean?
I don't understand a) at all but I *think* I understand b) like this:
If type is false then type will be equal to "fx" otherwise type will equal whatever it was before.
I'm not sure, but perhaps I'm wrong.
What is this syntax called? Conditional variable? :P I tried Googling for an answer but have no idea what to use in my query.
a)
time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
is synonym for
if (jQuery.fx) {
if (jQuery.fx.speeds[time]) {
time = jQuery.fx.speeds[time];
}
}
which is almost the same as
b)
type = type || "fx";
is synonym for
if (!type) {
type = "fx";
}
Simply it checks if type is not false, null, undefined. If yes, type is being filled with fx
For A, what we're doing is a shortcut for an if-else statement. The stuff before the question mark refers to the if statement, the next element is the "then" statement, and the final part is the "else" statement.
var action = my_status == 'hungry' ? 'eat' : 'do not eat';
In this case, it would translate into something like this:
if (my_status == 'hungry')
action = 'eat';
else
action = 'do not eat';
For B, double pipes (||) mean "or". What we're evaluating here is a Boolean value based on whether one OR the other is true.
var not_hungry = ate_lunch || full;
If either ate_lunch OR full is true, the not_hungry is also true.
You can do the same thing with double ampersands (&&) which mean AND.
var single = nerdy && cocky;
If nerdy AND cocky are true, then single is also true. If only one of those is true, then the statement resolves to false (since both must be true for single to be true).
Hope that helps. :)
Edit (h/t Phrogz):
It's worth noting that || and && in JavaScript don't only operate upon and evaluate to a Boolean value, but rather are "guard" operators that test for 'truthiness' and evaluate to one of the two operands. (
time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
Can be written as:
if (jQuery.fx) {
if (jQuery.fx.speeds[time]){
time = jQuery.fx.speeds[time];
}
}
In this case the ternary operation (? :) is redundant. The statement returns time if JQuery.fx.speeds[time] doesn't exist - so it returns itself.
More general: somevar = a || b is called short circuit evaluation. Basically it's a short way of writing
if (a) {
somevar = a;
} else {
somevar = b;
}
a) Set time to jQuery.fx.speeds[time] if and only if jQuery.fx and jQuery.fx.speeds[time] exists:
if(jQuery.fx && jQuery.fx.speeds[time])
time = jQuery.fx.speeds[time];
b) Your description is correct
a.) is structured using ternary operator, in simple term think of
time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
as equivalent to:
time = if(jQuery.fx){ jQuery.fx.speeds[time]; } else { time : time; }
b.) you are correct in that type will be defined if type is already defined, otherwise it'll default to "fx". However, I'm not sure if there's a technical name for it except it is the logical expression for OR
Yes, you're right about what it does. It's known as short-circuit evaluation. It does something similar to C's ternary operator.
It's a ternary operator
http://en.wikipedia.org/wiki/Ternary_operator
I was trying to link to the first result here...
https://www.google.com/#hl=en&cp=4&gs_id=1j&xhr=t&q=wiki+inline+if&
In javascript, if we have some code such as
var a = "one";
var b = q || a;
alert (b);
The logical OR operator will assign a's value to b, and the alert will be "one."
Is this limited to assignments only or can we use it everywhere?
It seems an empty string is treated the same as undefined. Is this right?
How does this work with AND variables? What about combinations of them?
What is a good example of when to use these idioms, or when not to?
For your q || a to evaluate to a, q should be a 'falsy' value. What you did is called "Short circuit evaluation".
Answering your questions:
The logical operators (like and - &&, or - ||) can be used in other situations too. More generally in conditional statements like if. More here
Empty string is not treated as undefined. Both are falsy values. There are a few more falsy values. More here
AND, or && in JavaScript, is not a variable. It is an operator
The idiom you have used is quite common.
var x = val || 'default'; //is generally a replacement for
var x = val ? val : 'default' //or
if (val)
var x = val;
else
var x = 'default';
The way || works in Javascript is:
If the left operand evaluates as true, return the left operand
Otherwise, return the right operand
&& works similarly.
You can make use of this for in-line existence checks, for example:
var foo = (obj && obj.property)
will set foo to obj.property if obj is defined and "truthy".
I'm not quite sure I follow your question. You can use an expression anywhere you can use an expression, and a logical operator on two expressions results in an expression.
alert(q||a);
alert(true||false);
var x=5;
var y=0;
if (y!=0 && x/y>2) { /*do something*/ }
The last bit is useful. Like most languages, Javascript 'short-circuits' ANDs and ORs. If the first part of an AND is false, it doesn't evaluate the second bit - saving you a divide-by-0. If the first part of an OR is true, it doesn't evaluate the second.
But you can use boolean operators anywhere you can use an expression.
Javascript evaluates logic by truethness/falseness. Values such as (false, "", null, undefined, 0, -0) are evaluated as logic false.
Combine this with the lazy evaluation, 'OR' operations are now evaluated from left to right and stops once true is found. Since, in your example, the truthness is not literally a boolean, the value is returned.
In this case:
x = 0; y = 5; alert(y || x)/*returns 5*/; alert(x || y)/*also returns 5*/;
this can also be other objects.
functionThatReturnsTrue() || functionThatDoesSomething();
This behavior is shared with other scripting languages like Perl. The logical OR operator can be used as a syntactic shorthand for specifying default values due to the fact that the logical OR operator stops evaluating its operands when it encounters the first expression that evaluates to true: "evaluate the first operand and if the value is interpreted as not false, assign it. Otherwise repeat for the second operand."
I find I often use this behavior to specify default values for function parameters. E.g.
function myFunction(foo, bar) {
var fooValue = foo || "a";
// no need to test fooValue -- it's guaranteed to be defined at this point
}
IMHO - don't use for boolean type assignment. It can be confusing. As undefined !== false, ie false itself is a value.
E.g. If u want to copy a field value from an object if and only if that field is defined
var bar.value = false;
var foo = true;
var foo = bar.value || foo; // ==> should be false as bar.value is defined
For boolean type assignment, u should really use
var foo = (bar.value !== undefined) ? bar.value : foo;
I have often used the following construct in Javascript:
var foo = other_var || "default_value";
In Javascript, if the left side is falsy, then the value on the right side is assigned.
It is very handy, and saves writing longer and unnecessarily explicit ternary expressions.
Is there a name for this sort of construct ?
Bonus: Is there a trick to do this in Php without using a ternary operator?
PS: another variant is to throw an error if you don't get a truthy value, instead of giving a default value:
var foo = something || alert("foo is not set!");
The logical-or (usually ||) operator is drastically different in many languages.
In some (like C, C++) it works like: "Evaluate the left-hand side; if it's true, return true, otherwise evaluate the right hand-side and return true if it's true or false otherwise." The result is always boolean here.
In others (like Javascript, Python, I believe that PHP also) it's more like: "Evaluate the left-hand side; if it's true, return it, otherwise evaluate the right-hand side and return the result." Then the result can be of any type and you can do constructs like:
a = (b || c); // equivalent to a = b ? b : c;
or quite fancy:
function compare(A, B) { // -1 if A<B, 0 if A==B, 1 if A>B
return B.x - A.x || B.y - A.y;
}
I believe it's just called an OR construct. There are a lot of good examples on using assignments here:
http://php.net/manual/en/language.operators.assignment.php
It is just a logical OR operator. Follow the link for more information in javascript.
From the examples in the docs:
o1=true || true // t || t returns true
o2=false || true // f || t returns true
o3=true || false // t || f returns true
o4=false || (3 == 4) // f || f returns false
o5="Cat" || "Dog" // t || t returns Cat
o6=false || "Cat" // f || t returns Cat
o7="Cat" || false // t || f returns Cat
EDIT: Regarding the BONUS, it appears as though you can do something similar with the ternary in recent versions of PHP by doing:
expr1 ?: expr3
From the PHP docs:
Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.
I'm not familiar with PHP, so I'd be interested to know the result.
This works:
$mytruevalue = true;
$foo = $mytruevalue or $foo = "20";
echo $foo;
The above prints "1" because that is the string representation of true ($mytruevalue is true).
$myfalsevalue = false;
$foo = $myfalsevalue or $foo = "20";
echo $foo;
This, however, prints "20" because $myfalsevalue is false.
If both values are equal to false, it prints nothing.
Hope this helps.
Is there a name for this sort of
construct ?
It is the logical OR operator.
Bonus: Is there a trick to do this in
Php without using a ternary operator?
No, with PHP, you can do so only with the help of ternay operator.
I've always had to put null in the else conditions that don't have anything. Is there a way around it?
For example,
condition ? x = true : null;
Basically, is there a way to do the following?
condition ? x = true;
Now it shows up as a syntax error.
FYI, here is some real example code:
!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null;
First of all, a ternary expression is not a replacement for an if/else construct - it's an equivalent to an if/else construct that returns a value. That is, an if/else clause is code, a ternary expression is an expression, meaning that it returns a value.
This means several things:
use ternary expressions only when you have a variable on the left side of the = that is to be assigned the return value
only use ternary expressions when the returned value is to be one of two values (or use nested expressions if that is fitting)
each part of the expression (after ? and after : ) should return a value without side effects (the expression x = true returns true as all expressions return the last value, but it also changes x without x having any effect on the returned value)
In short - the 'correct' use of a ternary expression is
var resultofexpression = conditionasboolean ? truepart: falsepart;
Instead of your example condition ? x=true : null ;, where you use a ternary expression to set the value of x, you can use this:
condition && (x = true);
This is still an expression and might therefore not pass validation, so an even better approach would be
void(condition && x = true);
The last one will pass validation.
But then again, if the expected value is a boolean, just use the result of the condition expression itself
var x = (condition); // var x = (foo == "bar");
UPDATE
In relation to your sample, this is probably more appropriate:
defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';
No, it needs three operands. That's why they're called ternary operators.
However, for what you have as your example, you can do this:
if(condition) x = true;
Although it's safer to have braces if you need to add more than one statement in the future:
if(condition) { x = true; }
Edit: Now that you mention the actual code in which your question applies to:
if(!defaults.slideshowWidth)
{ defaults.slideshowWidth = obj.find('img').width()+'px'; }
More often, people use logical operators to shorten the statement syntax:
!defaults.slideshowWidth &&
(defaults.slideshowWidth = obj.find('img').width() + 'px');
But in your particular case the syntax can be even simpler:
defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width() + 'px';
This code will return the defaults.slideshowWidth value if the defaults.slideshowWidth is evaluated to true and obj.find('img').width() + 'px' value otherwise.
See Short-Circuit Evaluation of logical operators for details.
var x = condition || null;
You could write
x = condition ? true : x;
So that x is unmodified when the condition is false.
This then is equivalent to
if (condition) x = true
EDIT:
!defaults.slideshowWidth
? defaults.slideshowWidth = obj.find('img').width()+'px'
: null
There are a couple of alternatives - I'm not saying these are better/worse - merely alternatives
Passing in null as the third parameter works because the existing value is null. If you refactor and change the condition, then there is a danger that this is no longer true. Passing in the exising value as the 2nd choice in the ternary guards against this:
!defaults.slideshowWidth =
? defaults.slideshowWidth = obj.find('img').width()+'px'
: defaults.slideshowwidth
Safer, but perhaps not as nice to look at, and more typing. In practice, I'd probably write
defaults.slideshowWidth = defaults.slideshowWidth
|| obj.find('img').width()+'px'
We also have now the "Nullish coalescing operator" (??). It works similar to the "OR" operator, but only returns the left expression if it's null or undefined, it doesn't return it for the other falsy values.
Example:
const color = undefined ?? 'black'; // color: 'black'
const color = '' ?? 'black'; // color: ''
const color = '#ABABAB' ?? 'black'; // color: '#ABABAB'
What about simply
if (condition) { code if condition = true };
To use a ternary operator without else inside of an array or object declaration, you can use the ES6 spread operator, ...():
const cond = false;
const arr = [
...(cond ? ['a'] : []),
'b',
];
// ['b']
And for objects:
const cond = false;
const obj = {
...(cond ? {a: 1} : {}),
b: 2,
};
// {b: 2}
Original source
In your case i see the ternary operator as redundant. You could assign the variable directly to the expression, using ||, && operators.
!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null ;
will become :
defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';
It's more clear, it's more "javascript" style.
You might consider using a guard expression instead (see Michael Thiessen's excellent article for more).
Let x be a logical expression, that you want to test, and z be the value you want to return, when x is true. You can then write:
y == x && z
If x is true, y evaluates to z. And if x is false, so is y.
The simple way to do this is:
if (y == x) z;
Why not writing a function to avoid the else condition?
Here is an example:
const when = (statement, text) => (statement) ? text : null;
const math = when(1 + 2 === 3, 'Math is correct');
const obj = when(typeof "Hello Word" === 'number', "Object is a string");
console.log(math);
console.log(obj);
You could also implement that function for any objects. Here is an example for the type string:
const when = (statement, text) => (statement) ? text : null;
String.prototype.if = when;
const msg = 'Hello World!';
const givenMsg = msg.if(msg.length > 0, 'There is a message! Yayyy!');
console.log(givenMsg);
Technically, it can return anything.
But, I would say for a one liner the Ternary is easier to type and at least 1 character shorter, so therefore faster.
passTest?hasDriversLicense=true:0
if(passTest)hasDriversLicense=true