- Notifications
You must be signed in to change notification settings - Fork333
💩State-of-the-art shitcode principles your project should follow to call it a proper shitcode
License
trekhleb/state-of-the-art-shitcode
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
This a list of state-of-the-art shitcode principles your project should follow to call it a proper shitcode.
Read this in other languages:简体中文,한국어
If your repository follows the state-of-the-art shitcode principles you may use the following "state-of-the-art shitcode" badge:
Markdown source-code for the badge:
[](https://github.com/trekhleb/state-of-the-art-shitcode)
Fewer keystrokes, more time for you.
Good 👍🏻
leta=42;
Bad 👎🏻
letage=42;
Celebrate the difference.
Good 👍🏻
letwWidth=640;letw_height=480;
Bad 👎🏻
letwindowWidth=640;letwindowHeight=480;
No one is going to read your code anyway.
Good 👍🏻
constcdr=700;
Bad 👎🏻
More often comments should contain some 'why' and not some 'what'. If the 'what' is not clear in the code, the code is probably too messy.
// The number of 700ms has been calculated empirically based on UX A/B test results.//@see: <link to experiment or to related JIRA task or to something that explains number 700 in details>constcallbackDebounceRate=700;
If you violated the "No comments" principle then at least try to write comments in a language that is different from the language you use to write the code. If your native language is English you may violate this principle.
Good 👍🏻
// Закриваємо модальне віконечко при виникненні помилки.toggleModal(false);
Bad 👎🏻
// Hide modal window on error.toggleModal(false);
Celebrate the difference.
Good 👍🏻
leti=['tomato','onion','mushrooms'];letd=["ketchup","mayonnaise"];
Bad 👎🏻
letingredients=['tomato','onion','mushrooms'];letdressings=['ketchup','mayonnaise'];
Good 👍🏻
document.location.search.replace(/(^\?)/,'').split('&').reduce(function(o,n){n=n.split('=');o[n[0]]=n[1];returno},{})
Bad 👎🏻
document.location.search.replace(/(^\?)/,'').split('&').reduce((searchParams,keyValuePair)=>{keyValuePair=keyValuePair.split('=');searchParams[keyValuePair[0]]=keyValuePair[1];returnsearchParams;},{})
Whenever you catch an error it is not necessary for anyone to know about it. No logs, no error modals, chill.
Good 👍🏻
try{// Something unpredictable.}catch(error){// tss... 🤫}
Bad 👎🏻
try{// Something unpredictable.}catch(error){setErrorMessage(error.message);// and/orlogError(error);}
Globalization principle.
Good 👍🏻
letx=5;functionsquare(){x=x**2;}square();// Now x is 25.
Bad 👎🏻
letx=5;functionsquare(num){returnnum**2;}x=square(x);// Now x is 25.
Just in case.
Good 👍🏻
functionsum(a,b,c){consttimeout=1300;constresult=a+b;returna+b;}
Bad 👎🏻
functionsum(a,b){returna+b;}
Good 👍🏻
functionsum(a,b){returna+b;}// Having untyped fun here.constguessWhat=sum([],{});// -> "[object Object]"constguessWhatAgain=sum({},[]);// -> 0
Bad 👎🏻
functionsum(a:number,b:number): ?number{// Covering the case when we don't do transpilation and/or Flow type checks in JS.if(typeofa!=='number'&&typeofb!=='number'){returnundefined;}returna+b;}// This one should fail during the transpilation/compilation.constguessWhat=sum([],{});// -> undefined
This is your "Plan B".
Good 👍🏻
functionsquare(num){if(typeofnum==='undefined'){returnundefined;}else{returnnum**2;}returnnull;// This is my "Plan B".}
Bad 👎🏻
functionsquare(num){if(typeofnum==='undefined'){returnundefined;}returnnum**2;}
Be like a bird - nest, nest, nest.
Good 👍🏻
functionsomeFunction(){if(condition1){if(condition2){asyncFunction(params,(result)=>{if(result){for(;;){if(condition3){}}}})}}}
Bad 👎🏻
asyncfunctionsomeFunction(){if(!condition1||!condition2){return;}constresult=awaitasyncFunction(params);if(!result){return;}for(;;){if(condition3){}}}
Avoid indentations since they make complex code take up more space in the editor. If you're not feeling like avoiding them then just mess with them.
Good 👍🏻
constfruits=['apple','orange','grape','pineapple'];consttoppings=['syrup','cream','jam','chocolate'];constdesserts=[];fruits.forEach(fruit=>{toppings.forEach(topping=>{desserts.push([fruit,topping]);});})
Bad 👎🏻
constfruits=['apple','orange','grape','pineapple'];consttoppings=['syrup','cream','jam','chocolate'];constdesserts=[];fruits.forEach(fruit=>{toppings.forEach(topping=>{desserts.push([fruit,topping]);});})
Update your dependencies on each new installation in uncontrolled way. Why stick to the past, let's use the cutting edge libraries versions.
Good 👍🏻
$ ls -lapackage.json
Bad 👎🏻
$ ls -lapackage.jsonpackage-lock.json
Leave the space for your colleagues to think what the boolean value means.
Good 👍🏻
letflag=true;
Bad 👎🏻
letisDone=false;letisEmpty=false;
Don't divide a program logic into readable pieces. What if your IDE's search breaks and you will not be able to find the necessary file or function?
- 10000 lines of code in one file is OK.
- 1000 lines of a function body is OK.
- Dealing with many services (3rd party and internal, also, there are some helpers, database hand-written ORM and jQuery slider) in one
service.js
? It's OK.
This is a duplicate and unnecessary amount of work.
Write code as you want, especially if there is more than one developer in a team. This is a "freedom" principle.
And keep it that way for the time being.
Don't delete the code your app doesn't use. At most, comment it.