Closed cerlestes closed 8 years ago
@cerlestes Can you create a PR for it?
I'll see if I can come up with an interesting text. No promises though :)
Maybe we could improve this very good tip and add that it can be useful mostly to make sure your code is by any means impossible to read.
Jokes aside, there are cases where this might be useful though, let's say you are maintaining a library and you want the code to be better gzipped by suppressing unnecessary indexed substring such as :
and ?
for ternary operators that are not being used anywhere else.
Other than that, there is no real value for this in most real world applications, the only use is if the developer wants to feel smart or turn the code impossible to read.
@FagnerMartinsBrack I disagree. It's not widely used apart from the following case, but there it makes a lot of sense to use the operators in that way and even increases readability dramatically:
{
url: options.url,
data: options.data || fallback || {},
type: options.type || 'text/json'
}
I agree that it can be used in wrong ways, but the tip should of course also explain that. The wrong way to use this is to execute code, just like with the ternary operator:
// Bad use of logical AND:
shouldExecute && execute();
// Bad use of ternary operator:
(shouldExecute) ? execute() : foobar();
// Correct way: use if-construct to execute code
if (shouldExecute) {
execute();
}
Please note that I didn't want to include my examples from the original post in the tip, as they're purely for demonstrating how it works. Of course no actualy production code should look like them.
It's not widely used apart from the following case, but there it makes a lot of sense to use the operators in that way and even increases readability dramatically:
You got me with the logical OR. This one is widely used for default values in ES5:
var item = items[index] || {}
Although in ES6 with default parameters the idea is that it starts to be used less often.
Your second example clearly explain what I mean, using logical operators for cases where a regular imperative if
would make much more sense.
@cerlestes = D Thanks for the interesting post
Although I don't have much knowledge of gzipping and bad use of ternary operator mentioned in previous comments, I have a use case of ternary operator. Please bear with me if it turns out to be bad practice : )
Some really simple if statement could be saved by using ternary operator
We could have
var count = i % 2 ? 6 : 7;
instead of
....
if (i % 2 == 0) {
count = 7;
} else{
count = 6;
}
//or something like this
var count = 6;
if (i % 2 == 0) {
count = 7;
}
In this case, I was rendering a "hive" with several lines of hexagons. The odd number of line has 6 hexagons each line, and the even one has 7.
Similarly, another example:
// var data = [...{"Hero":"valla","ID":"'14' ","Free":true}...]
var overlay = data[i]['Free'] ? $('<div class="overlay free" > </div> ')
: $('<div class="overlay" > </div> ');
If Free is true, .free class will be added to the element.
Personally, logical operators are readable unless they are overly used. Furthermore, considering about the spacing issue of squeezing several really simple if statements into for loops, logical operator might be a better approach in my opinion.
Hope this helps! Thanks for your patience. ^ ^
Personally, logical operators are readable unless they are overly used. Furthermore, considering about the spacing issue of squeezing several really simple if statements into for loops, logical operator might be a better approach in my opinion.
const metaPool = [
['sane_gentoo_commands','Sane Gentoo Commands','May 7, 2016','Gentoo'],
['sane_gentoo_repo','Sane Gentoo Repository','May 8, 2016',''],
['random_post3','Random post 3','May 19, 2016',''],
['run', 'Decreased the blog loading time - again', 'May 26, 2016', ''],
['back_to_the_future', 'Back to the future', 'May 31, 2016', ''],
['jblogfy', 'My 3rd static generator', 'June 01, 2016', ''],
['templating','Learn to love the ES6 native templating','June 04, 2016','JavaScript,ES6,ESNEXT']
];
const capFirst = text => text.charAt(0).toUpperCase() +
text.slice(1).toLowerCase();
const postTemplate = arr => `
<div id='progress-bar' class='hide'>
<div id='cur-progress' class='progress-bar'></div>
</div>
<article class='details-wrapper'>
<div class='details-head'>
<div class='details-head-wrapper'>
<h6 id='details-title'></h6>
${arr[1][0] ?
`<span>
Post Categories:\u00A0
</span>` : '' }
${arr[1][0] ?
arr[1].map(curCat => `
<a href='#!category=${curCat}'>
<span class='label label-default'>
${capFirst(curCat)}
</span>
</a>\u00A0
`).join('') : ''}
</div>
</div>
<div id='details-body'>
</div>
<div class='details-footer'>
<hr>
<span>
The source file for this entry can be found <a id='md-src'>Here</a>
</span>
</div>
<ul class='pager'>
${metaPool[arr[0] - 1] ? `
<li class='previous'>
<a href='#!post=${metaPool[arr[0]-1][0]}'>
← Older
</a>
</li>
`: ''}
${metaPool[arr[0] + 1] ? `
<li class='next'>
<a href='#!post=${metaPool[arr[0]+1][0]}'>
Newer →
</a>
</li>
` : ''}
</ul>
</article>
`;
console.log(postTemplate([
1,
metaPool[1][3].toLowerCase().split(',')
]));
console.log(postTemplate([
6,
metaPool[6][3].toLowerCase().split(',')
]));
@wifiextender Is that unmaintainable code you posted supposed to prove something?
I can perfectly understand what's going on. Comments would be nice though (but not sure where to integrate them)
Comments would be nice though
There is also the alternative of trying to write legible code instead of writing comments to workaround it.
What exactly isn't understandable? Even through my gmail app I could read the code, with syntax highlighting it's even easier.
What exactly isn't understandable? Even through my gmail app I could read the code, with syntax highlighting it's even easier.
Code should be self documented. If the developer judges that a code need comments (as you proposed), then that is a strong indication that the code is not legible enough. If it was legible enough, then the need for comments explaining what the code is doing would be unnecessary.
@FagnerMartinsBrack Your <= ES5 and readable alternative without using templating engine is ?
const titlenLinkTemplate = arr => `
${arr.map(el => `
<h4 class='entry-title'>
<a href='${el[0]}' class='snippet-title text-muted'>
${capFirst(el[1])}
</a>
</h4>
<hr>
`).join('')
}
`;
console.log(titlenLinkTemplate(metaPool));
@kurtextrem Thanks for the support.
@wifiextender
@FagnerMartinsBrack Your <= ES5 and readable alternative without using templating engine is ?
Using a proper view framework like React without trying to reinvent the wheel with plain JavaScript.
I am not saying that isn't a smart approach for templating, it is, but there are two kinds of smart solutions: The one that want to focus in being smart and focus in irrelevant performance at the cost of legibility, and the one that focus in solving problems with proper legibility at the cost of irrelevant performance.
Nobody can provide an alternative for that code because it is impossible to know what it is trying to achieve, and the code itself cannot express clearly what it is trying to do. Architecture starts from the problem and goes up to the implementation, without knowing the problem it is impossible to suggest a different implementation, infering the problem from a snippet of code is dangerous, for that we might be missing important context. I can bet though that the problem could be fixed without having to create tons of arr[1][0]
, [arr[0] - 1]
, : '' }
and [6][3].toLowerCase().split(',')
tokens that mean nothing to the reader.
JavaScript is not there yet, unfortunately.
Nobody can provide an alternative for that code because it is impossible to know what it is trying to achieve, and the code itself cannot express clearly what it is trying to do.
Same could be said for your statement:
Using a proper view framework like React without trying to reinvent the wheel with plain JavaScript.
When you complete porting my last and short example to ES5, you'll build the confidence that you can solve my first example. Upon trying it, you'll start losing track what's going on, the code will become more unreadable and you'll end up frustrated yelling at your screen. Then you'll realize what's the big deal of templating languages engines and frameworks such as React you mentioned earlier in the <= ES5 era.
I'll butt out of this conversation for now, until some close-minded and moaning people are gone as they brought here only negativism without contributing back something useful.
When you complete porting my last and short example to ES5, you'll build the confidence that you can solve my first example.
I never said anything about ES5, you did.
Upon trying it, you'll start losing track what's going on, the code will become more unreadable and you'll end up frustrated yelling at your screen.
Lots of assumptions and argument against a straw man that you created about this ES5 thing that I never mentioned.
Then you'll realize what's the big deal of templating languages engines and frameworks such as React you mentioned earlier in the <= ES5 era.
I never mentioned it is better to use React in <= ES5 era, I mentioned it is better using React, it doesn't matter which ES version. My arguments were against the way variables in the template were structured using plain JS, not about using the concept of templates or ES5/ES6/etc.. The code is just reinventing React and all implicit scope features (that cannot be seen in the code) unnecessarily, doing such thing take time and resources of any project.
TL;DR:
Please come back with a PR. We can debate when we review it.
First, awesome repository; I love it!
Now my suggestion for another tip: In my opinion, one of the best things about JS is the lax and kind of lazy way in which the logical operators
||
(logical OR, "default operator") and&&
(logical AND, "guard operator") work. Basically: OR will yield the left value if truthy, otherwise the right value; AND will yield the right value if both are truthy, otherwise the falsy is yielded. So to say: the value that matters, that makes or breaks the comparison, is yielded. They don't convert to boolean, because of JS's inherent way of handling truthy/falsy values. You can use them in some very fantastic ways. This would make for a very interesting article.