[Reading notes] 5 tips for you to write better JavaScript [picture]

When using JavaScript, we often have to write a lot of conditional statements. Here are five tips that will allow you to write cleaner and more beautiful conditional statements.
Use Array.includes to handle multiple conditions
For example:
//conditional statement
functiontest(fruit){
if(fruit=='apple'||fruit=='strawberry'){
console.log('red');
}
}
At first glance, this seems to be no big problem.
However, what if we want to match more red fruits, such as "cherries" and "cranberries"? Do we have to use more || to extend this sentence?
We can use Array.includes to rewrite the above conditional sentence.
functiontest(fruit){
//Extract the conditions to the array
constredFruits=['apple','strawberry','cherry','cranberries'];
if(redFruits.includes(fruit)){
console.log('red' );
}
}
We extract all the red fruits (conditions) into an array, which makes our code look cleaner.
[Reading notes] 5 tips for you to write better JavaScript [picture]
Write less nesting and return
as soon as possible. Let us add two conditions to the previous example:
if no fruit is provided, throw an error;
if the number of the fruit is greater than 10, print it out.
functiontest(fruit,quantity){
constredFruits=['apple','strawberry','cherry','cranberries'];
//condition 1: fruit must have a value
if(fruit){
//condition 2: must be red
if (redFruits.includes(fruit)){
console.log('red');
//Condition 3: Must exist in large quantities
if(quantity>10){
console.log('bigquantity');
}
}
}else{
thrownewError( 'Nofruit!');
}
}
//Test result
test(null);//Error: Nofruits
test('apple');//Print: red
test('apple',20);//Print: red, bigquantity
Let us take a closer look at the above code, we have:
1 if/else statement to filter invalid conditions;
3 levels of if statement nesting (condition 1, 2 & 3).

JavaScript(简称“JS”) 是一种具有函数优先的轻量级,解释型或即时编译型的高级编程语言。虽然它是作为开发Web页面的脚本语言而出名的,读书笔记https://www.yuananren.com但是它也被用到了很多非浏览器环境中,JavaScript 基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式和声明式(如函数式编程)风格。
就我个人而言,我遵循的一个总的规则是当发现无效条件时尽早返回。

/ Return as soon as possible when invalid conditions are found /
functiontest(fruit,quantity){
constredFruits=['apple','strawberry','cherry','cranberries'];
//Condition 1: throw an error as early as possible
if(!fruit) thrownewError('Nofruit!');
//Condition 2: Must be red
if(redFruits.includes(fruit)){
console.log('red');
//Condition 3: Must be a large amount
if(quantity>10) {
console.log('bigquantity');
}
}
}
In this way, we write less nesting. This is a good coding style, especially when the if statement is very long (just imagine, you have to scroll to the bottom to know that there is an else statement, is it a bit uncomfortable).
If we reverse the conditions, we can further reduce the nesting level. Pay attention to the following condition 2 statement to see how to do this:
/ return as soon as possible when an invalid condition is found /
functiontest(fruit,quantity){
constredFruits=['apple','strawberry','cherry',' cranberries'];
if(!fruit) thrownewError('Nofruit!');//Condition 1: Throw an error as early as possible
if(!redFruits.includes(fruit))return;//Condition 2: When the fruit is not red, return directly to the
console. log('red');
//Condition 3: There must be a large number of
if(quantity>10){
console.log('bigquantity');
}
}
By reversing the condition of Condition 2, now our code has no nesting Up.
This technique is very useful when the logic chain of our code is very long and we hope that the subsequent process will not be executed when a certain condition is not met.
However, there are no hard and fast rules that require you to do this. It's up to you. For you, is this version of the code (without nesting) better and more readable than the previous version (with condition 2 nesting)?
If it's me, I will choose the previous version (condition 2 has nesting). The reason is:
such code is relatively short and straightforward, a nested if makes the structure clearer;
conditional inversion will lead to more thinking process (increasing cognitive burden).
Therefore, always pursue less nesting and return earlier, but don't overdo it.
If you are interested, here is an article on this issue and a discussion on StackOverflow:
AvoidElse, ReturnEarlybyTimOxley
StackOverflowdiscussiononif/elsecodingstyle
Use function default parameters and deconstruction
I guess you may be familiar with the following code. In JavaScript, we often need to check for null/undefined and assign default values:
functiontest(fruit,quantity){
if(!fruit)return;
constq=quantity||1;//if not Provide quantity, default is 1
console.log( Wehave${q}${fruit}!);
}
//Test result
test('banana');//Wehave1banana!
test('apple',2);//Wehave2apple!
In fact, we can pass the default function Parameters to remove the variable q.
functiontest(fruit,quantity=1){//If quantity is not provided, the default is 1
if(!fruit)return;
console.log( Wehave${quantity}${fruit}!);
}
//Test result
test('banana');//Wehave1banana!
test( 'apple',2);//Wehave2apple!
Is it simpler and more straightforward?
Please note that all function parameters can have default values. For example, we can also assign a default value to fruit:
functiontest(fruit='unknown',quantity=1).
So what if fruit is an Object? Can we still use the default parameters?
functiontest(fruit){
//If there is a value, print it out
if(fruit&&fruit.name){
console.log(fruit.name);
}else{
console.log('unknown');
}
}
//Test result
test( undefined);//unknown
test({});//unknown
test({name:'apple',color:'red'});//apple
observe the above example, when the fruit name attribute exists, we hope to change Print it out, otherwise print "unknown".
We can avoid the condition of writing fruit&&fruit.name by default parameters and destructuring assignment methods.
//Deconstruction-only get the name attribute
//The default parameter is an empty object{}
functiontest({name}={}){
console.log(name||'unknown');
}
//Test result
test(undefined); //unknown
test({});//unknown
test({name:'apple',color:'red'});

We also use {} as its default value.
If we don't do this
, you will get an error Cannotdestructurepropertynameof'undefined'or'null'. when executing test(undefined),
because there is no name property on undefined.
(Translator's Note: This is not very accurate, in fact, because destructuring only applies to objects, not because there is no name attribute on undefined (neither on empty objects). Refer to Destructuring Assignment-MDN)
If you don’t mind using the first For tripartite libraries, there are some ways to help reduce null checks:
use the Lodashget function;
use Facebook's open-source idx library (with Babeljs).
Here is an example of using Lodash:
//Use the method


provided by the lodash library functiontest(fruit){ //Get the value of the attribute name, if not, set it to the default value unknown console.log( .get(fruit,'name', 'unknown');
}
//test result
test(undefined);//unknown
test(());//unknown
test((name:'apple',color:'red'));//apple
you can Run the demo code here.
In addition, if you prefer functional programming (FP), you can choose to use Lodashfp-the functional version of Lodash (method name becomes get or getOr).
Compared to switch, Map/Object may be a better choice.
Let us look at the following example, we want to print out various fruits according to color:
functiontest(color){
//Use switchcase to find the fruit of the corresponding color
switch(color ){
case'red':
return['apple','strawberry'];
case'yellow':
return['banana','pineapple'];
case'purple':
return['grape','plum'];
default:
return[];
}
}
//test result
test(null);//[]
test('yellow');//['banana','pineapple'] The
above code does not seem to be wrong, but just Personally, it looks very verbose. The same result can be achieved by object literals, and the syntax is more concise:
//Use object literals to find the fruit of the corresponding color
constfruitColor={
red:['apple','

purple:['grape','plum']
};
functiontest(color){
returnfruitColor[color]||[];
}
Or, you can also use Map to achieve the same effect:
//Use Map to find the corresponding color Fruit
constfruitColor=newMap()
.set('red',['apple','strawberry'])
.set('yellow',['banana','pineapple'])
.set('purple',['grape ','plum']);
functiontest(color){
returnfruitColor.get(color)||[];
}
Map is a new object type introduced by ES2015, allowing you to store key-value pairs.
Does that mean that we should prohibit the use of switch statements? Don't limit yourself.
I myself use object literals whenever possible, but that doesn’t mean I don’t need to switch, it depends on the scene.
ToddMotto has an article that discusses switch statements and object literals in depth, and you might want to check it out.
Lazy version: Refactoring syntax
is the above example. In fact, we can use Array.filter to achieve the same effect by refactoring our code.
constfruits=[
{name:'
{name:'strawberry',color:'red'},
{name:'banana',color:'yellow'},
{name:'pineapple',color:'yellow'},
{name:'grape',color :'purple'},
{name:'plum',color:'purple'}
];
functiontest(color){
//Use Arrayfilter to find the fruit of the corresponding color
returnfruits.filter(f=>f.color==color) ;
}There
is never only one way to solve a problem. For this example we show four implementation methods.
Codingisfun!
Use Array.every and Array.some to handle all/partially satisfying conditions. The
last tip is more about using new (and not very new) JavaScript array functions to reduce the number of lines of code.
Observe the following code, we want to check whether all fruits are red:
constfruits=[
{name:'apple',color:'red'},
{name:'banana',color:'yellow'},
{ name:'grape',color:'purple'}
];



for(letfoffruits){
if(!isAllRed)break;
isAllRed=(f.color=='red');
}
console.log(isAllRed);//false
}
This code is too long! We can reduce the code through Array.every
constfruits=[
(name:'apple',color:'red'),
(name:'banana',color:'yellow'),
(name:'grape',color:' purple'}
];
functiontest(){
//Condition: (short form) all fruits must be red
constisAllRed=fruits.every(f=>f.color=='red');
console.log(isAllRed); //false
}It's
much clearer, right?
Similarly, if we want to check whether at least one fruit is red, we can use Array.some to achieve it with just one line of code.
constfruits=[
{name:'apple',color:'red'},
{name:'banana',color:'yellow'},
{name:'grape',


//Condition: At least one fruit is red
constisAnyRed=fruits.some(f=>f.color=='red');
console.log(isAnyRed);//true
}
Let us write it together and make it more readable The code. Hope this article can bring you some help. That's it~ Happycoding!

Guess you like

Origin blog.51cto.com/14938467/2539463