├── .gitignore ├── .editorconfig ├── LICENSE ├── CODE_OF_CONDUCT.md ├── README.zh-CN.md ├── README.ko-KR.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Oleksii Trekhleb 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Scope 35 | 36 | This Code of Conduct applies both within project spaces and in public spaces 37 | when an individual is representing the project or its community. Examples of 38 | representing a project or community include using an official project e-mail 39 | address, posting via an official social media account, or acting as an appointed 40 | representative at an online or offline event. Representation of a project may be 41 | further defined and clarified by project maintainers. 42 | 43 | ## Enforcement 44 | 45 | Project maintainers who do not follow or enforce the Code of Conduct in good 46 | faith may face temporary or permanent repercussions as determined by other 47 | members of the project's leadership. 48 | 49 | ## Attribution 50 | 51 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 52 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 53 | 54 | [homepage]: https://www.contributor-covenant.org 55 | 56 | For answers to common questions about this code of conduct, see 57 | https://www.contributor-covenant.org/faq 58 | -------------------------------------------------------------------------------- /README.zh-CN.md: -------------------------------------------------------------------------------- 1 | # 垃圾代码书写准则 2 | 3 | [![State-of-the-art Shitcode](https://img.shields.io/static/v1?label=State-of-the-art&message=Shitcode&color=7B5804)](https://github.com/trekhleb/state-of-the-art-shitcode) 4 | 5 | 这是一个你的项目应该遵循的垃圾代码书写准则的列表,把称为适当的垃圾代码。 6 | 7 | _Read this in other languages:_ 8 | [_English_](README.md), 9 | [_한국어_](README.ko-KR.md) 10 | 11 | ## 获取徽章 12 | 13 | 如果你的仓库遵循垃圾代码书写准则,你应该用下面的"state-of-the-art shitcode" 徽章: 14 | 15 | [![State-of-the-art Shitcode](https://img.shields.io/static/v1?label=State-of-the-art&message=Shitcode&color=7B5804)](https://github.com/trekhleb/state-of-the-art-shitcode) 16 | 17 | 标记徽章的源代码: 18 | 19 | ``` 20 | [![State-of-the-art Shitcode](https://img.shields.io/static/v1?label=State-of-the-art&message=Shitcode&color=7B5804)](https://github.com/trekhleb/state-of-the-art-shitcode) 21 | ``` 22 | 23 | ## 准则 24 | 25 | ### 💩 以一种代码已经被混淆的方式命名变量 26 | 27 | 如果我们键入的东西越少,那么就有越多的时间去思考代码逻辑等问题。 28 | 29 | _Good 👍🏻_ 30 | 31 | ```javascript 32 | let a = 42; 33 | ``` 34 | 35 | _Bad 👎🏻_ 36 | 37 | ```javascript 38 | let age = 42; 39 | ``` 40 | 41 | ### 💩 变量/函数混合命名风格 42 | 43 | 为不同庆祝一下。 44 | 45 | _Good 👍🏻_ 46 | 47 | ```javascript 48 | let wWidth = 640; 49 | let w_height = 480; 50 | ``` 51 | 52 | _Bad 👎🏻_ 53 | 54 | ```javascript 55 | let windowWidth = 640; 56 | let windowHeight = 480; 57 | ``` 58 | 59 | ### 💩 不要写注释 60 | 61 | 反正没人会读你的代码。 62 | 63 | _Good 👍🏻_ 64 | 65 | ```javascript 66 | const cdr = 700; 67 | ``` 68 | 69 | _Bad 👎🏻_ 70 | 71 | 更多时候,评论应该包含一些“为什么”,而不是一些“是什么”。如果“什么”在代码中不清楚,那么代码可能太混乱了。 72 | 73 | ```javascript 74 | // 700ms的数量是根据UX A/B测试结果进行经验计算的。 75 | // @查看: <详细解释700的一个链接> 76 | const callbackDebounceRate = 700; 77 | ``` 78 | 79 | ### 💩 使用母语写注释 80 | 81 | 如果您违反了“无注释”原则,那么至少尝试用一种不同于您用来编写代码的语言来编写注释。如果你的母语是英语,你可能会违反这个原则。 82 | 83 | _Good 👍🏻_ 84 | 85 | ```javascript 86 | // Закриваємо модальне віконечко при виникненні помилки. 87 | toggleModal(false); 88 | ``` 89 | 90 | _Bad 👎🏻_ 91 | 92 | ```javascript 93 | // 隐藏错误弹窗 94 | toggleModal(false); 95 | ``` 96 | 97 | ### 💩 尽可能混合不同的格式 98 | 99 | 为不同庆祝一下。 100 | 101 | _Good 👍🏻_ 102 | 103 | ```javascript 104 | let i = ['tomato', 'onion', 'mushrooms']; 105 | let d = [ "ketchup", "mayonnaise" ]; 106 | ``` 107 | 108 | _Bad 👎🏻_ 109 | 110 | ```javascript 111 | let ingredients = ['tomato', 'onion', 'mushrooms']; 112 | let dressings = ['ketchup', 'mayonnaise']; 113 | ``` 114 | 115 | ### 💩 尽可能把代码写成一行 116 | 117 | _Good 👍🏻_ 118 | 119 | ```javascript 120 | document.location.search.replace(/(^\?)/,'').split('&').reduce(function(o,n){n=n.split('=');o[n[0]]=n[1];return o},{}) 121 | ``` 122 | 123 | _Bad 👎🏻_ 124 | 125 | ```javascript 126 | document.location.search 127 | .replace(/(^\?)/, '') 128 | .split('&') 129 | .reduce((searchParams, keyValuePair) => { 130 | keyValuePair = keyValuePair.split('='); 131 | searchParams[keyValuePair[0]] = keyValuePair[1]; 132 | return searchParams; 133 | }, 134 | {} 135 | ) 136 | ``` 137 | 138 | ### 💩 不要处理错误 139 | 140 | 无论何时发现错误,都没有必要让任何人知道它。没有日志,没有错误弹框。 141 | 142 | _Good 👍🏻_ 143 | 144 | ```javascript 145 | try { 146 | // 意料之外的情况。 147 | } catch (error) { 148 | // tss... 🤫 149 | } 150 | ``` 151 | 152 | _Bad 👎🏻_ 153 | 154 | ```javascript 155 | try { 156 | // 意料之外的情况。 157 | } catch (error) { 158 | setErrorMessage(error.message); 159 | // and/or 160 | logError(error); 161 | } 162 | ``` 163 | 164 | ### 💩 广泛使用全局变量 165 | 166 | 全球化的原则。 167 | 168 | _Good 👍🏻_ 169 | 170 | ```javascript 171 | let x = 5; 172 | 173 | function square() { 174 | x = x ** 2; 175 | } 176 | 177 | square(); // 现在x是25 178 | ``` 179 | 180 | _Bad 👎🏻_ 181 | 182 | ```javascript 183 | let x = 5; 184 | 185 | function square(num) { 186 | return num ** 2; 187 | } 188 | 189 | x = square(x); // 现在x是25 190 | ``` 191 | 192 | ### 💩 创建你不会使用的变量 193 | 194 | 以防万一。 195 | 196 | _Good 👍🏻_ 197 | 198 | ```javascript 199 | function sum(a, b, c) { 200 | const timeout = 1300; 201 | const result = a + b; 202 | return a + b; 203 | } 204 | ``` 205 | 206 | _Bad 👎🏻_ 207 | 208 | ```javascript 209 | function sum(a, b) { 210 | return a + b; 211 | } 212 | ``` 213 | 214 | ### 💩 如果语言允许,不要指定类型和/或不执行类型检查。 215 | 216 | _Good 👍🏻_ 217 | 218 | ```javascript 219 | function sum(a, b) { 220 | return a + b; 221 | } 222 | 223 | // 在这里享受没有注释的快乐 224 | const guessWhat = sum([], {}); // -> "[object Object]" 225 | const guessWhatAgain = sum({}, []); // -> 0 226 | ``` 227 | 228 | _Bad 👎🏻_ 229 | 230 | ```javascript 231 | function sum(a: number, b: number): ?number { 232 | // 当我们在JS中不做置换和/或流类型检查时,覆盖这种情况。 233 | if (typeof a !== 'number' && typeof b !== 'number') { 234 | return undefined; 235 | } 236 | return a + b; 237 | } 238 | 239 | // 这个应该在转换/编译期间失败。 240 | const guessWhat = sum([], {}); // -> undefined 241 | ``` 242 | 243 | ### 💩 你应该有不能到达的代码 244 | 245 | 这是你的 "Plan B". 246 | 247 | _Good 👍🏻_ 248 | 249 | ```javascript 250 | function square(num) { 251 | if (typeof num === 'undefined') { 252 | return undefined; 253 | } 254 | else { 255 | return num ** 2; 256 | } 257 | return null; // 这就是我的"Plan B". 258 | } 259 | ``` 260 | 261 | _Bad 👎🏻_ 262 | 263 | ```javascript 264 | function square(num) { 265 | if (typeof num === 'undefined') { 266 | return undefined; 267 | } 268 | return num ** 2; 269 | } 270 | ``` 271 | 272 | ### 💩 三角法则 273 | 274 | 就像鸟巢,鸟巢,鸟巢。 275 | 276 | _Good 👍🏻_ 277 | 278 | ```javascript 279 | function someFunction() { 280 | if (condition1) { 281 | if (condition2) { 282 | asyncFunction(params, (result) => { 283 | if (result) { 284 | for (;;) { 285 | if (condition3) { 286 | } 287 | } 288 | } 289 | }) 290 | } 291 | } 292 | } 293 | ``` 294 | 295 | _Bad 👎🏻_ 296 | 297 | ```javascript 298 | async function someFunction() { 299 | if (!condition1 || !condition2) { 300 | return; 301 | } 302 | 303 | const result = await asyncFunction(params); 304 | if (!result) { 305 | return; 306 | } 307 | 308 | for (;;) { 309 | if (condition3) { 310 | } 311 | } 312 | } 313 | ``` 314 | 315 | ### 💩 混合缩进 316 | 317 | 避免缩进,因为它们会使复杂的代码在编辑器中占用更多的空间。如果你不喜欢回避他们,那就和他们捣乱。 318 | 319 | _Good 👍🏻_ 320 | 321 | ```javascript 322 | const fruits = ['apple', 323 | 'orange', 'grape', 'pineapple']; 324 | const toppings = ['syrup', 'cream', 325 | 'jam', 326 | 'chocolate']; 327 | const desserts = []; 328 | fruits.forEach(fruit => { 329 | toppings.forEach(topping => { 330 | desserts.push([ 331 | fruit,topping]); 332 | });}) 333 | ``` 334 | 335 | _Bad 👎🏻_ 336 | 337 | ```javascript 338 | const fruits = ['apple', 'orange', 'grape', 'pineapple']; 339 | const toppings = ['syrup', 'cream', 'jam', 'chocolate']; 340 | const desserts = []; 341 | 342 | fruits.forEach(fruit => { 343 | toppings.forEach(topping => { 344 | desserts.push([fruit, topping]); 345 | }); 346 | }) 347 | ``` 348 | 349 | ### 💩 不要锁住你的依赖项 350 | 351 | 以非受控方式更新每个新安装的依赖项。为什么坚持使用过去的版本,让我们使用最先进的库版本。 352 | 353 | _Good 👍🏻_ 354 | 355 | ``` 356 | $ ls -la 357 | 358 | package.json 359 | ``` 360 | 361 | _Bad 👎🏻_ 362 | 363 | ``` 364 | $ ls -la 365 | 366 | package.json 367 | package-lock.json 368 | ``` 369 | 370 | ### 💩 函数长的比短的好 371 | 372 | 不要把程序逻辑分成可读的部分。如果IDE的搜索停止,而您无法找到所需的文件或函数,该怎么办? 373 | 374 | - 一个文件中10000行代码是OK的。 375 | - 一个函数体有1000行代码是OK的。 376 | - 在一个' service.js ' 中处理许多服务(第三方库和内部库、一些工具、手写的数据库ORM和jQuery滑块)? 这是OK的。 377 | 378 | ### 💩 不要测试你的代码 379 | 380 | 这是重复且不需要的工作。 381 | 382 | ### 💩 避免代码风格统一 383 | 384 | 编写您想要的代码,特别是在一个团队中有多个开发人员的情况下。这是“自由”原则。 385 | 386 | ### 💩 构建新项目不需要 README 文档 387 | 388 | 一开始我们就应该保持。 389 | 390 | ### 💩 保存不必要的代码 391 | 392 | 不要删除不用的代码,最多注释掉。 393 | -------------------------------------------------------------------------------- /README.ko-KR.md: -------------------------------------------------------------------------------- 1 | # State-of-the-Art Shitcode의 규칙 2 | 3 | [![State-of-the-art Shitcode](https://img.shields.io/static/v1?label=State-of-the-art&message=Shitcode&color=7B5804)](https://github.com/trekhleb/state-of-the-art-shitcode) 4 | 5 | 이 목록은 여러분의 프로젝트가 제대로 shitcode가 되기 위해 따라야 하는 규칙들입니다. 6 | 7 | _다른 언어로 읽기:_ 8 | [_English_](README.md), 9 | [_简体中文_](README.zh-CN.md) 10 | 11 | ## 뱃지 만들기 12 | 13 | 만일 여러분의 레포지토리가 shitcode의 규칙을 따른다면, 여러분은 다음과 같은 "state-of-the-art shitcode" 뱃지를 사용할 수 있습니다: 14 | 15 | [![State-of-the-art Shitcode](https://img.shields.io/static/v1?label=State-of-the-art&message=Shitcode&color=7B5804)](https://github.com/trekhleb/state-of-the-art-shitcode) 16 | 17 | 뱃지를 만들기 위한 마크다운 소스코드: 18 | 19 | ``` 20 | [![State-of-the-art Shitcode](https://img.shields.io/static/v1?label=State-of-the-art&message=Shitcode&color=7B5804)](https://github.com/trekhleb/state-of-the-art-shitcode) 21 | ``` 22 | 23 | ## 규칙 24 | 25 | ### 💩 변수 이름 애매하게 지정하기 26 | 27 | 적은 키 입력은, 여러분의 시간을 아끼게 해줍니다. 28 | 29 | _Good 👍🏻_ 30 | 31 | ```javascript 32 | let a = 42; 33 | ``` 34 | 35 | _Bad 👎🏻_ 36 | 37 | ```javascript 38 | let age = 42; 39 | ``` 40 | 41 | ### 💩 변수와 함수의 이름 스타일을 섞기 42 | 43 | 다양성을 축하합시다. 44 | 45 | _Good 👍🏻_ 46 | 47 | ```javascript 48 | let wWidth = 640; 49 | let w_height = 480; 50 | ``` 51 | 52 | _Bad 👎🏻_ 53 | 54 | ```javascript 55 | let windowWidth = 640; 56 | let windowHeight = 480; 57 | ``` 58 | 59 | ### 💩 주석을 전혀 작성하지 않기 60 | 61 | 어차피 아무도 당신의 코드를 읽지 않을 것입니다. 62 | 63 | _Good 👍🏻_ 64 | 65 | ```javascript 66 | const cdr = 700; 67 | ``` 68 | 69 | _Bad 👎🏻_ 70 | 71 | 자주 작성되는 주석은 '왜'가 아니라 '무엇'인지를 포함해야 합니다. 만일 코드에서 '무엇'이 명확하지 않으면, 코드가 너무 흐트러질 수 있기 때문입니다. 72 | 73 | ```javascript 74 | // 700ms라는 수는 UX A/B 테스트 결과에 기초하여 경험적으로 계산된 것입니다. 75 | // @보세요: <실험 또는 JIRA 작업에 관련된 것 또는 숫자 700에 대해 상세히 설명하는 것에 대한 링크> 76 | const callbackDebounceRate = 700; 77 | ``` 78 | 79 | ### 💩 항상 자신의 모국어로 주석을 작성하기 80 | 81 | 만일 "주석 없음"의 원칙을 위반했다면 적어도 주석은 코드 작성에 사용하는 언어와 다른 언어로 작성하세요. 만일 여러분의 모국어가 영어라면 여러분은 이 원칙을 위반해도 괜찮습니다. 82 | 83 | _Good 👍🏻_ 84 | 85 | ```javascript 86 | // Закриваємо модальне віконечко при виникненні помилки. 87 | toggleModal(false); 88 | ``` 89 | 90 | _Bad 👎🏻_ 91 | 92 | ```javascript 93 | // Hide modal window on error. 94 | toggleModal(false); 95 | ``` 96 | 97 | ### 💩 가능한 많이 서식 스타일을 혼합하기 98 | 99 | 다양성을 축하합시다. 100 | 101 | _Good 👍🏻_ 102 | 103 | ```javascript 104 | let i = ['tomato', 'onion', 'mushrooms']; 105 | let d = [ "ketchup", "mayonnaise" ]; 106 | ``` 107 | 108 | _Bad 👎🏻_ 109 | 110 | ```javascript 111 | let ingredients = ['tomato', 'onion', 'mushrooms']; 112 | let dressings = ['ketchup', 'mayonnaise']; 113 | ``` 114 | 115 | ### 💩 가능한 많이 한 줄에 코드 입력하기 116 | 117 | _Good 👍🏻_ 118 | 119 | ```javascript 120 | document.location.search.replace(/(^\?)/,'').split('&').reduce(function(o,n){n=n.split('=');o[n[0]]=n[1];return o},{}) 121 | ``` 122 | 123 | _Bad 👎🏻_ 124 | 125 | ```javascript 126 | document.location.search 127 | .replace(/(^\?)/, '') 128 | .split('&') 129 | .reduce((searchParams, keyValuePair) => { 130 | keyValuePair = keyValuePair.split('='); 131 | searchParams[keyValuePair[0]] = keyValuePair[1]; 132 | return searchParams; 133 | }, 134 | {} 135 | ) 136 | ``` 137 | 138 | ### 💩 조용히 실패하기 139 | 140 | 오류가 발생할 때마다 다른 사람이 그 오류를 알 필요는 없습니다. 로그도 없고, 오류 모달도 없이, 싸늘하게. 141 | 142 | _Good 👍🏻_ 143 | 144 | ```javascript 145 | try { 146 | // 무언가 예견 불가능한 것. 147 | } catch (error) { 148 | // 쉿... 🤫 149 | } 150 | ``` 151 | 152 | _Bad 👎🏻_ 153 | 154 | ```javascript 155 | try { 156 | // 무언가 예견 불가능한 것. 157 | } catch (error) { 158 | setErrorMessage(error.message); 159 | // and/or 160 | logError(error); 161 | } 162 | ``` 163 | 164 | ### 💩 전역 변수를 광범위하게 사용하기 165 | 166 | 세계적인 원칙입니다. 167 | 168 | _Good 👍🏻_ 169 | 170 | ```javascript 171 | let x = 5; 172 | 173 | function square() { 174 | x = x ** 2; 175 | } 176 | 177 | square(); // 이제 x는 25입니다. 178 | ``` 179 | 180 | _Bad 👎🏻_ 181 | 182 | ```javascript 183 | let x = 5; 184 | 185 | function square(num) { 186 | return num ** 2; 187 | } 188 | 189 | x = square(x); // 이제 x는 25입니다. 190 | ``` 191 | 192 | ### 💩 사용하지 않을 변수 만들기 193 | 194 | 혹시 모르니까요. 195 | 196 | _Good 👍🏻_ 197 | 198 | ```javascript 199 | function sum(a, b, c) { 200 | const timeout = 1300; 201 | const result = a + b; 202 | return a + b; 203 | } 204 | ``` 205 | 206 | _Bad 👎🏻_ 207 | 208 | ```javascript 209 | function sum(a, b) { 210 | return a + b; 211 | } 212 | ``` 213 | 214 | ### 💩 가능한 언어라면 타입지정 및/또는 타입검사 하지 않기 215 | 216 | _Good 👍🏻_ 217 | 218 | ```javascript 219 | function sum(a, b) { 220 | return a + b; 221 | } 222 | 223 | // 형식이 없으면 신이 나요. 224 | const guessWhat = sum([], {}); // -> "[object Object]" 225 | const guessWhatAgain = sum({}, []); // -> 0 226 | ``` 227 | 228 | _Bad 👎🏻_ 229 | 230 | ```javascript 231 | function sum(a: number, b: number): ?number { 232 | // 자바스크립트에서 반환 및/또는 타입검사를 하지 않은 경우를 커버하는 조건 233 | if (typeof a !== 'number' && typeof b !== 'number') { 234 | return undefined; 235 | } 236 | return a + b; 237 | } 238 | // 이 경우는 반환/컴파일의 경우에 실패할 것입니다. 239 | const guessWhat = sum([], {}); // -> undefined 240 | ``` 241 | 242 | ### 💩 연결할 수 없는 코드 작성하기 243 | 244 | 이 것이 여러분의 "플랜 B" 입니다. 245 | 246 | _Good 👍🏻_ 247 | 248 | ```javascript 249 | function square(num) { 250 | if (typeof num === 'undefined') { 251 | return undefined; 252 | } 253 | else { 254 | return num ** 2; 255 | } 256 | return null; // 이 것이 나의 "플랜 B". 257 | } 258 | ``` 259 | 260 | _Bad 👎🏻_ 261 | 262 | ```javascript 263 | function square(num) { 264 | if (typeof num === 'undefined') { 265 | return undefined; 266 | } 267 | return num ** 2; 268 | } 269 | ``` 270 | 271 | ### 💩 삼각형 규칙 272 | 273 | 새처럼 되자 - 둥지를 틀자, 둥지를 틀자, 둥지를 틀자. 274 | 275 | _Good 👍🏻_ 276 | 277 | ```javascript 278 | function someFunction() { 279 | if (condition1) { 280 | if (condition2) { 281 | asyncFunction(params, (result) => { 282 | if (result) { 283 | for (;;) { 284 | if (condition3) { 285 | } 286 | } 287 | } 288 | }) 289 | } 290 | } 291 | } 292 | ``` 293 | 294 | _Bad 👎🏻_ 295 | 296 | ```javascript 297 | async function someFunction() { 298 | if (!condition1 || !condition2) { 299 | return; 300 | } 301 | 302 | const result = await asyncFunction(params); 303 | if (!result) { 304 | return; 305 | } 306 | 307 | for (;;) { 308 | if (condition3) { 309 | } 310 | } 311 | } 312 | ``` 313 | 314 | ### 💩 들여쓰기 망치기 315 | 316 | 들여쓰기는 에디터에서 복잡한 코드의 공간을 더 차지하기 때문에 들여쓰기를 피합시다. 만약 피하고 싶지 않다면 그냥 그들을 엉망으로 가지고 노세요. 317 | 318 | _Good 👍🏻_ 319 | 320 | ```javascript 321 | const fruits = ['apple', 322 | 'orange', 'grape', 'pineapple']; 323 | const toppings = ['syrup', 'cream', 324 | 'jam', 325 | 'chocolate']; 326 | const desserts = []; 327 | fruits.forEach(fruit => { 328 | toppings.forEach(topping => { 329 | desserts.push([ 330 | fruit,topping]); 331 | });}) 332 | ``` 333 | 334 | _Bad 👎🏻_ 335 | 336 | ```javascript 337 | const fruits = ['apple', 'orange', 'grape', 'pineapple']; 338 | const toppings = ['syrup', 'cream', 'jam', 'chocolate']; 339 | const desserts = []; 340 | 341 | fruits.forEach(fruit => { 342 | toppings.forEach(topping => { 343 | desserts.push([fruit, topping]); 344 | }); 345 | }) 346 | ``` 347 | 348 | ### 💩 dependencies 잠그지 않기 349 | 350 | 새로운 설치가 있을 때마다 제어되지 않는 방식으로 dependencies를 업데이트 하세요. 왜 과거에 집착하죠, 최첨단 라이브러리 버전을 사용합시다. 351 | 352 | _Good 👍🏻_ 353 | 354 | ``` 355 | $ ls -la 356 | 357 | package.json 358 | ``` 359 | 360 | _Bad 👎🏻_ 361 | 362 | ``` 363 | $ ls -la 364 | 365 | package.json 366 | package-lock.json 367 | ``` 368 | 369 | ### 💩 항상 boolean 타입 변수의 이름을 'flag'로 만들기 370 | 371 | boolean 값이 무엇을 의미하는지 동료들이 생각할 공간을 남겨둡시다. 372 | 373 | _Good 👍🏻_ 374 | 375 | ```javascript 376 | let flag = true; 377 | ``` 378 | 379 | _Bad 👎🏻_ 380 | 381 | ```javascript 382 | let isDone = false; 383 | let isEmpty = false; 384 | ``` 385 | 386 | ### 💩 길게 쓰인 function들이 짧은 것보다 낫다. 387 | 388 | 프로그램 로직을 읽을 수 있는 조각으로 나누지 맙시다. 만일 여러분이 사용하는 IDE의 검색이 중단되고 필수적인 파일 또는 function을 찾을 수 없다면 어떻게 하겠습니까? 389 | 390 | - 한 개의 파일에 10000 줄의 코드가 있어도 괜찮습니다. 391 | - 한 개의 function에 1000 줄의 코드가 있어도 괜찮습니다. 392 | - 많은 서비스들 (써드파티와 내부기능, 몇몇 헬퍼들, ORM과 jQuery slider로 직접 작성된 자료들 ) 이 `service.js` 하나에 들어있다구요? 괜찮습니다. 393 | 394 | ### 💩 작성한 코드를 테스트 해보는 것을 피하기 395 | 396 | 이 것은 중복되고 불필요한 일의 양입니다. 397 | 398 | ### 💩 최대한 code linter들을 피하려고 노력하기 399 | 400 | 특히 둘 이상의 개발자가 있는 팀인 경우 원하는 대로 코드를 작성합니다. 이것은 '자유'의 규칙입니다. 401 | 402 | ### 💩 README 파일이 없이 프로젝트 시작하기 403 | 404 | 그리고 당분간은 그렇게 지내세요. 405 | 406 | ### 💩 불필요한 코드가 필요합니다 407 | 408 | 어플에서 사용하지 않는 코드를 삭제하지 마세요. 기껏해야, 주석정도 입니다. 409 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # State-of-the-Art Shitcode Principles 2 | 3 | [![State-of-the-art Shitcode](https://img.shields.io/static/v1?label=State-of-the-art&message=Shitcode&color=7B5804)](https://github.com/trekhleb/state-of-the-art-shitcode) 4 | 5 | This a list of state-of-the-art shitcode principles your project should follow to call it a proper shitcode. 6 | 7 | _Read this in other languages:_ 8 | [_简体中文_](README.zh-CN.md), 9 | [_한국어_](README.ko-KR.md) 10 | 11 | ## Get Your Badge 12 | 13 | If your repository follows the state-of-the-art shitcode principles you may use the following "state-of-the-art shitcode" badge: 14 | 15 | [![State-of-the-art Shitcode](https://img.shields.io/static/v1?label=State-of-the-art&message=Shitcode&color=7B5804)](https://github.com/trekhleb/state-of-the-art-shitcode) 16 | 17 | Markdown source-code for the badge: 18 | 19 | ``` 20 | [![State-of-the-art Shitcode](https://img.shields.io/static/v1?label=State-of-the-art&message=Shitcode&color=7B5804)](https://github.com/trekhleb/state-of-the-art-shitcode) 21 | ``` 22 | 23 | ## The Principles 24 | 25 | ### 💩 Name variables in a way as if your code was already obfuscated 26 | 27 | Fewer keystrokes, more time for you. 28 | 29 | _Good 👍🏻_ 30 | 31 | ```javascript 32 | let a = 42; 33 | ``` 34 | 35 | _Bad 👎🏻_ 36 | 37 | ```javascript 38 | let age = 42; 39 | ``` 40 | 41 | ### 💩 Mix variable/functions naming style 42 | 43 | Celebrate the difference. 44 | 45 | _Good 👍🏻_ 46 | 47 | ```javascript 48 | let wWidth = 640; 49 | let w_height = 480; 50 | ``` 51 | 52 | _Bad 👎🏻_ 53 | 54 | ```javascript 55 | let windowWidth = 640; 56 | let windowHeight = 480; 57 | ``` 58 | 59 | ### 💩 Never write comments 60 | 61 | No one is going to read your code anyway. 62 | 63 | _Good 👍🏻_ 64 | 65 | ```javascript 66 | const cdr = 700; 67 | ``` 68 | 69 | _Bad 👎🏻_ 70 | 71 | 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. 72 | 73 | ```javascript 74 | // The number of 700ms has been calculated empirically based on UX A/B test results. 75 | // @see: 76 | const callbackDebounceRate = 700; 77 | ``` 78 | 79 | ### 💩 Always write comments in your native language 80 | 81 | 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. 82 | 83 | _Good 👍🏻_ 84 | 85 | ```javascript 86 | // Закриваємо модальне віконечко при виникненні помилки. 87 | toggleModal(false); 88 | ``` 89 | 90 | _Bad 👎🏻_ 91 | 92 | ```javascript 93 | // Hide modal window on error. 94 | toggleModal(false); 95 | ``` 96 | 97 | ### 💩 Try to mix formatting style as much as possible 98 | 99 | Celebrate the difference. 100 | 101 | _Good 👍🏻_ 102 | 103 | ```javascript 104 | let i = ['tomato', 'onion', 'mushrooms']; 105 | let d = [ "ketchup", "mayonnaise" ]; 106 | ``` 107 | 108 | _Bad 👎🏻_ 109 | 110 | ```javascript 111 | let ingredients = ['tomato', 'onion', 'mushrooms']; 112 | let dressings = ['ketchup', 'mayonnaise']; 113 | ``` 114 | 115 | ### 💩 Put as much code as possible into one line 116 | 117 | _Good 👍🏻_ 118 | 119 | ```javascript 120 | document.location.search.replace(/(^\?)/,'').split('&').reduce(function(o,n){n=n.split('=');o[n[0]]=n[1];return o},{}) 121 | ``` 122 | 123 | _Bad 👎🏻_ 124 | 125 | ```javascript 126 | document.location.search 127 | .replace(/(^\?)/, '') 128 | .split('&') 129 | .reduce((searchParams, keyValuePair) => { 130 | keyValuePair = keyValuePair.split('='); 131 | searchParams[keyValuePair[0]] = keyValuePair[1]; 132 | return searchParams; 133 | }, 134 | {} 135 | ) 136 | ``` 137 | 138 | ### 💩 Fail silently 139 | 140 | Whenever you catch an error it is not necessary for anyone to know about it. No logs, no error modals, chill. 141 | 142 | _Good 👍🏻_ 143 | 144 | ```javascript 145 | try { 146 | // Something unpredictable. 147 | } catch (error) { 148 | // tss... 🤫 149 | } 150 | ``` 151 | 152 | _Bad 👎🏻_ 153 | 154 | ```javascript 155 | try { 156 | // Something unpredictable. 157 | } catch (error) { 158 | setErrorMessage(error.message); 159 | // and/or 160 | logError(error); 161 | } 162 | ``` 163 | 164 | ### 💩 Use global variables extensively 165 | 166 | Globalization principle. 167 | 168 | _Good 👍🏻_ 169 | 170 | ```javascript 171 | let x = 5; 172 | 173 | function square() { 174 | x = x ** 2; 175 | } 176 | 177 | square(); // Now x is 25. 178 | ``` 179 | 180 | _Bad 👎🏻_ 181 | 182 | ```javascript 183 | let x = 5; 184 | 185 | function square(num) { 186 | return num ** 2; 187 | } 188 | 189 | x = square(x); // Now x is 25. 190 | ``` 191 | 192 | ### 💩 Create variables that you're not going to use. 193 | 194 | Just in case. 195 | 196 | _Good 👍🏻_ 197 | 198 | ```javascript 199 | function sum(a, b, c) { 200 | const timeout = 1300; 201 | const result = a + b; 202 | return a + b; 203 | } 204 | ``` 205 | 206 | _Bad 👎🏻_ 207 | 208 | ```javascript 209 | function sum(a, b) { 210 | return a + b; 211 | } 212 | ``` 213 | 214 | ### 💩 Don't specify types and/or don't do type checks if language allows you to do so. 215 | 216 | _Good 👍🏻_ 217 | 218 | ```javascript 219 | function sum(a, b) { 220 | return a + b; 221 | } 222 | 223 | // Having untyped fun here. 224 | const guessWhat = sum([], {}); // -> "[object Object]" 225 | const guessWhatAgain = sum({}, []); // -> 0 226 | ``` 227 | 228 | _Bad 👎🏻_ 229 | 230 | ```javascript 231 | function sum(a: number, b: number): ?number { 232 | // Covering the case when we don't do transpilation and/or Flow type checks in JS. 233 | if (typeof a !== 'number' && typeof b !== 'number') { 234 | return undefined; 235 | } 236 | return a + b; 237 | } 238 | 239 | // This one should fail during the transpilation/compilation. 240 | const guessWhat = sum([], {}); // -> undefined 241 | ``` 242 | 243 | ### 💩 You need to have an unreachable piece of code 244 | 245 | This is your "Plan B". 246 | 247 | _Good 👍🏻_ 248 | 249 | ```javascript 250 | function square(num) { 251 | if (typeof num === 'undefined') { 252 | return undefined; 253 | } 254 | else { 255 | return num ** 2; 256 | } 257 | return null; // This is my "Plan B". 258 | } 259 | ``` 260 | 261 | _Bad 👎🏻_ 262 | 263 | ```javascript 264 | function square(num) { 265 | if (typeof num === 'undefined') { 266 | return undefined; 267 | } 268 | return num ** 2; 269 | } 270 | ``` 271 | 272 | ### 💩 Triangle principle 273 | 274 | Be like a bird - nest, nest, nest. 275 | 276 | _Good 👍🏻_ 277 | 278 | ```javascript 279 | function someFunction() { 280 | if (condition1) { 281 | if (condition2) { 282 | asyncFunction(params, (result) => { 283 | if (result) { 284 | for (;;) { 285 | if (condition3) { 286 | } 287 | } 288 | } 289 | }) 290 | } 291 | } 292 | } 293 | ``` 294 | 295 | _Bad 👎🏻_ 296 | 297 | ```javascript 298 | async function someFunction() { 299 | if (!condition1 || !condition2) { 300 | return; 301 | } 302 | 303 | const result = await asyncFunction(params); 304 | if (!result) { 305 | return; 306 | } 307 | 308 | for (;;) { 309 | if (condition3) { 310 | } 311 | } 312 | } 313 | ``` 314 | 315 | ### 💩 Mess with indentations 316 | 317 | 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. 318 | 319 | _Good 👍🏻_ 320 | 321 | ```javascript 322 | const fruits = ['apple', 323 | 'orange', 'grape', 'pineapple']; 324 | const toppings = ['syrup', 'cream', 325 | 'jam', 326 | 'chocolate']; 327 | const desserts = []; 328 | fruits.forEach(fruit => { 329 | toppings.forEach(topping => { 330 | desserts.push([ 331 | fruit,topping]); 332 | });}) 333 | ``` 334 | 335 | _Bad 👎🏻_ 336 | 337 | ```javascript 338 | const fruits = ['apple', 'orange', 'grape', 'pineapple']; 339 | const toppings = ['syrup', 'cream', 'jam', 'chocolate']; 340 | const desserts = []; 341 | 342 | fruits.forEach(fruit => { 343 | toppings.forEach(topping => { 344 | desserts.push([fruit, topping]); 345 | }); 346 | }) 347 | ``` 348 | 349 | ### 💩 Do not lock your dependencies 350 | 351 | Update your dependencies on each new installation in uncontrolled way. Why stick to the past, let's use the cutting edge libraries versions. 352 | 353 | _Good 👍🏻_ 354 | 355 | ``` 356 | $ ls -la 357 | 358 | package.json 359 | ``` 360 | 361 | _Bad 👎🏻_ 362 | 363 | ``` 364 | $ ls -la 365 | 366 | package.json 367 | package-lock.json 368 | ``` 369 | 370 | ### 💩 Always name your boolean value a `flag` 371 | 372 | Leave the space for your colleagues to think what the boolean value means. 373 | 374 | _Good 👍🏻_ 375 | 376 | ```javascript 377 | let flag = true; 378 | ``` 379 | 380 | _Bad 👎🏻_ 381 | 382 | ```javascript 383 | let isDone = false; 384 | let isEmpty = false; 385 | ``` 386 | 387 | ### 💩 Long-read functions are better than short ones. 388 | 389 | 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? 390 | 391 | - 10000 lines of code in one file is OK. 392 | - 1000 lines of a function body is OK. 393 | - 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. 394 | 395 | ### 💩 Avoid covering your code with tests 396 | 397 | This is a duplicate and unnecessary amount of work. 398 | 399 | ### 💩 As hard as you can try to avoid code linters 400 | 401 | Write code as you want, especially if there is more than one developer in a team. This is a "freedom" principle. 402 | 403 | ### 💩 Start your project without a README file. 404 | 405 | And keep it that way for the time being. 406 | 407 | ### 💩 You need to have unnecessary code 408 | 409 | Don't delete the code your app doesn't use. At most, comment it. 410 | --------------------------------------------------------------------------------