I have been reviewing other peoples javascript codes and noticed variable lines like this:
opacity = isIn ? 0 : 1;,
opacity = isIn ? opacity + gap : opacity - gap;,
var s = this == binary ? h(binary, f, change, text) : h(text, r, change2, binary);,
And other lines of code like that. How do they work? What type of variable are they?
Thank you so much!
This is a special form of if called a conditional (or ternary) operator:
var value = condition ? value_when_true : value_when_false;
If the condition evaluates to true, value will be assigned value_when_true, if not, value_when_false.
It is functionally the same as:
var value;
if (condition) {
value = value_when_true;
} else {
value = value_when_false;
}
See this MDN article for detailed description.
Its called ternary operators
http://msdn.microsoft.com/en-us/library/ie/be21c7hw%28v=vs.94%29.aspx
var s = (some_condition) ? if_true_value : if_false_value;
same as
if(some_condition){
s = if_true_value;
}else{
s = if_false_value;
}
Related
I would like to clean up my code but I can't. I would like to get rid of the nested ternary expressions. I work with react js 17.0.2. Do you have any ideas to help me?
const buildNewFilters = (query, filtersIndex: Array<string>) => {
const newFilters = {};
for (let i = 0; i < filtersIndex.length; i++) {
newFilters[filtersIndex[i]] = router.query[filtersIndex[i]] ? typeof router.query[filtersIndex[i]] == ('string' || 'number') ? [router.query[filtersIndex[i]]] : router.query[filtersIndex[i]] : undefined
if (filtersIndex[i] === 'designers' && newFilters.designers) {
newFilters.designers = newFilters.designers.map(designer => parseInt(designer));
}
}
return newFilters;
};
if (router.query[filtersIndex[i]]) {
if (typeof router.query[filtersIndex[i]] == ("string" || "number")) {
newFilters[filtersIndex[i]] = [router.query[filtersIndex[i]]];
} else {
newFilters[filtersIndex[i]] = router.query[filtersIndex[i]];
}
} else {
newFilters[filtersIndex[i]] = undefined;
}
If you are not used to working with ternary operators, I understand that it's not easy to refactor the code. First, you can read about what ternary expressions are and try them out in the Mozilla Documentation about ternary operators. Basically the part of the code before the ? evaluates to either true or false and if it evaluates to true, the part before the subsequent : is executed (in your case assigned to the variable newFilters[filtersIndex[i]], otherwise the part after the : will be assigned to the variable.
My tip would be to put the line you want to refactor in a text editor to experiment with it, and add line breaks and/or tabs after the ? and : signs to see the structure better and to see what is happening at each step.
In PHP, say if I have code like this:
$aValue = functionThatReturnsAValue(); // the function might return a string or null;
$anotherValue = $aValue ? process($aValue) : null;
only for brievity (IDK is this a good practice or not and also regarding the performance, etc), I used to change the code like so:
$anotherValue = ($aValue = functionThatReturnsAValue()) ? process($aValue) : null;
My questions are:
Is this style even a good practice?
How can I use this with JavaScript? I wrote with same style but got error.
Thank you.
You could use a logical AND && and process only a given value.
If aValue is null or a falsy value, this value is assigned to anotherValue, otherwise, it takes the value of process(aValue).
anotherValue = (aValue = functionThatReturnsAValue()) && process(aValue);
Since aValue is the value returned from executing functionThatReturnsAValue(), You can try this
var anotherValue = (functionThatReturnsAValue()) ? process(functionThatReturnsAValue()) : null;
The isCheck() function returns false if not radio buttons have been checked.
if (isCheck() === false) {
i = 0;
return i;
}
yes it works. alternatively you could use ternary operator
using that syntax:
test ? expression1 : expression2
for example :
//init var i with some value
var i = 1;
function isCheck(){ return false;}
i = isCheck() === false ? 0 : i;
return i;
or simple:
//before you should initialize i
return !isCheck() ? 0 : i ;
There is no wrong in executing a function inside if conditional statement.
For such case you can use ternary operator
var i=-1; // Note var key word & initialized with some value
isCheck() === false ? (i=0):(i=someOtherVal)
I don't see why not, some will say its not conventional but it should work just fine!
Yes it is correct
You dont need to create a variable only to receive a bool and later do a validation you can do directly.
Hi Guys I’m having trouble trying to set a variable (val) to be one of 2 possible object attributes. The below code explains what I’m trying to do.
function myFnct(elem, imgSrcType) {
var val = imgSrcType == "bg" ? elem.style.backgroundImage : elem.src;
val = 'image.jpg'
}
I’m using a ternary operator to try and avoid having to write:
if (imgSrcType === "bg") {
elem.style.backgroundImage = "url('image.jpg')";
}
else {
elem.src = "image.jpg";
}
Basically the ‘val’ variable is not getting set correctly as I guess its something to do with elem object. I’m trying to avoid using the if statement as I will need to use it a few times within the function. And I’m trying to keep is as DRY as possible.
Any help getting it to work with the ternary operator method would be awesome!
if (imgSrcType === "bg") {
elem.style.backgroundImage = "url('image.jpg')";
}
else {
elem.src = "image.jpg";
}
ugly but working rewrite:
void (
imgSrcType === 'bg'
&& (elem.style.backgroundImage = "url('image.jpg')")
|| (elem.src = "image.jpg")
);
Equals:
void (
imgSrcType === 'bg'
? (elem.style.backgroundImage = "url('image.jpg')")
: (elem.src = "image.jpg")
);
So by adding parentheses (elem.src = "image.jpg") you can do the assignment. You can also use a comma to return something in a value assignment.
Using this knowledge, you could rewrite myFnct:
function myFnct(elem, imgSrcType) {
var val = (
void( imgSrcType == "bg"
? (elem.style.backgroundImage = "url('image.jpg')")
: (elem.src = "image.jpg") ), //<= ternary done - comma
'image.jpg'
);
//now val = 'image.jpg'
}
Note: this is all about what is possible. If you need/want to keep your code readable, using the if ... else statement is the better option.
Ternary operations can only assign their outcome to a single variable. They are useful if you are setting that single variable to different values depending on the result of a boolean expression. Since you are trying to assign the image URL to either the background-image or to the source, you cannot use a simple ternary operation. The other answers are using pretty complex/quasi-obfuscated code to accomplish what could be done with a simple if/else statement. Your code - especially for such a simple operation - should be easy to read. So, I recommend just sticking with the following:
function setImage(elem, imgSrcType)
{
var imgURL = "image.jpg";
if(imgSrcType == "bg")
{
elem.style.backgroundImage = "url('" + imgURL + "')";
}
else
{
elem.src = imgURL;
}
}
I have an object menuNames which should maintain a list of menu items. If menuNames already has the slug, increment the value, if it doesnt contain the slug, set the value equal to 1. I'm doing this to track unique names. I want to end up with something like:
menuNames: {
home: 1,
products: 10,
contact: 1
}
this doesnt work (this would be contained in a loop going through each slug):
menuNames[slug] = (menuNames.hasOwnProperty(slug) ? menuNames[slug]++ : 1);
//this sets every value to 1
but this does work (this would be contained in a loop going through each slug):
if(menuNames.hasOwnProperty(slug)) {
menuNames[slug]++;
} else {
menuNames[slug] = 1;
}
menuNames[slug]++ increments the value, but also returns the original value.
You are doing menuNames[slug] =, so the value is set back to the original value after being incremented.
To fix it, just simply do:
menuNames[slug] = (menuNames.hasOwnProperty(slug) ? menuNames[slug]+1 : 1);
Or:
(menuNames.hasOwnProperty(slug) ? menuNames[slug]++ : menuNames[slug] = 1);
I guess it could work like this:
menuNames[slug] = (menuNames.hasOwnProperty(slug) ? ++menuNames[slug] : 1);
As the other answers say the problem is in the post increment.
Another way to write it is:
menuNames[slug] += (some_bool ? 1 : 0);
++ is very sensitive to bugs. Try to write it as a += statement.
if menuNames[slug] can be undefined, write it as:
menuNames[slug] = 0;
if (some_bool) {
menuNames[slug] += 1;
}
This is (in my opinion) the clearest way to write an initialization/counter loop.
If you like one-liners you'll cringe, but if you like bug free code you'll be happy to see this.