Home >Web Front-end >JS Tutorial >12 Tips for Writing Clean and Scalable JavaScript Code
JavaScript originated from the early days of the Internet. It started as a scripting language and has now evolved into a fully fledged programming language supporting server-side execution.
Modern web applications rely heavily on JavaScript, especially single-page applications (SPA). With emerging frameworks like React, AngularJS, and Vue.js, web applications are primarily built using JavaScript.
Scaling these applications (the front end is equivalent to the back end) can be quite tricky. With a mediocre setup, you'll end up hitting limitations and getting lost in a sea of confusion. I want to share some tips to help you write clean code in an efficient way.
This article is suitable for JavaScript developers of any skill level. However, developers with at least intermediate knowledge of JavaScript will benefit the most from these tips.
The most important thing I can suggest to keep your codebase clean and readable is to separate specific logic by topic Block (usually a function). If you write a function, it should default to having only one purpose and should not perform multiple operations at once.
Also, causing side effects should be avoided, which means that in most cases, anything declared outside a function should not be changed. Receive data into a function with parameters; everything else should not be accessed. If you want to get something from the function, return a new value.
Of course, you can combine multiple functions if they are used in similar ways or do similar things Grouped into a module (and/or class, if you prefer). For example, if you have many different calculations to do, you can split them into independent steps (functions) that can be chained.
However, these functions can be declared in a file (module). Here is a JavaScript example:
function add(a, b) { return a + b } function subtract(a, b) { return a - b } module.exports = { add, subtract } const { add, subtract } = require('./calculations') console.log(subtract(5, add(3, 2))
If you are writing front-end JavaScript, be sure to use default exports for your most important projects and named exports for less important projects.
When declaring a function, multiple parameters should always be preferred instead of Not a parameter that requires an object:
// GOOD function displayUser(firstName, lastName, age) { console.log(`This is ${firstName} ${lastName}. She is ${age} years old.`) } // BAD function displayUser(user) { console.log(`This is ${user.firstName} ${user.lastName}. She is ${user.age} years old.`) }
The reason behind this is that when you look at the first line of the function declaration, you know exactly what needs to be passed to the function.
Although the size of the function should be limited (do only one job), the size of the function can become larger. It will take more time to find the variables that need to be passed in the function body (nested in the object). Sometimes it seems easier to use the whole object and pass it to the function, but to scale the application, this setup will definitely help.
At some point, it doesn't make sense to declare specific parameters. For me, it's more than four or five function parameters. If your function gets that big, you should use object parameters.
The main reason here is that the parameters need to be passed in a specific order. If there are optional parameters, you need to pass undefined
or null
. Using object parameters you can simply pass the entire object where order and undefined values don't matter.
Destructuring is a good tool introduced in ES6. It allows you to get a specific field from an object and assign it to a variable immediately. You can use it with any type of object or module.
// EXAMPLE FOR MODULES const { add, subtract } = require('./calculations')
It makes sense to import only the functions that need to be used in the file, rather than the entire module and then access specific functions from it. Similarly, Destructuring can also be used when you are sure that you really need an object as a function argument. This will still give you an overview of what you need inside the function:
function logCountry({name, code, language, currency, population, continent}) { let msg = `The official language of ${name} ` if(code) msg += `(${code}) ` msg += `is ${language}. ${population} inhabitants pay in ${currency}.` if(contintent) msg += ` The country is located in ${continent}` } logCountry({ name: 'Germany', code: 'DE', language 'german', currency: 'Euro', population: '82 Million', }) logCountry({ name: 'China', language 'mandarin', currency: 'Renminbi', population: '1.4 Billion', continent: 'Asia', })
destructured default values or even basic Function parameters are very useful. First, they give you an example of the values you can pass to the function. Second, you indicate which values are required and which are not. Using the previous example, the complete setup of the function might look like this:
function logCountry({ name = 'United States', code, language = 'English', currency = 'USD', population = '327 Million', continent, }) { let msg = `The official language of ${name} ` if(code) msg += `(${code}) ` msg += `is ${language}. ${population} inhabitants pay in ${currency}.` if(contintent) msg += ` The country is located in ${continent}` } logCountry({ name: 'Germany', code: 'DE', language 'german', currency: 'Euro', population: '82 Million', }) logCountry({ name: 'China', language 'mandarin', currency: 'Renminbi', population: '1.4 Billion', continent: 'Asia', })
Obviously, sometimes you may not want to use a default value and instead throw an error when no value is passed. However, this is often a convenient trick.
The previous tips let us come to a conclusion: do not pass unnecessary data. Here, again, this may mean more work when setting up functions, but it will definitely give you a more readable code base in the long run. Knowing exactly which values were used at a particular location is extremely valuable.
I have seen large files—very large files. In fact, there are over 3,000 lines of code. It is difficult to find logical blocks in these files.
因此,您应该将文件大小限制为一定数量的行。我倾向于将文件保存在100行代码以下有时,很难分解文件,它们将增长到200-300行,在极少数情况下,最多可达400行。
超过此阈值,文件将变得混乱且难以维护。随意创建新的模块和文件夹。您的项目应该看起来像一个森林,由树(模块部分)和分支(模块和模块文件的组)组成。
相比之下,您的实际文件应该看起来像shire,到处都有一些小山(小凹痕),但所有文件都相对平坦。尽量使缩进水平保持在4以下。
在团队中工作需要清晰的样式指南和格式。ESLint提供了一个巨大的规则集,您可以根据需要进行自定义还有eslint--fix,它纠正了一些错误,但不是全部。
相反,我建议使用Prettier来格式化代码。这样,开发人员就不必担心代码格式化,而只需编写高质量的代码。外观将是一致的,格式自动。
理想情况下,应该根据变量的内容为其命名。下面是一些指导原则,可以帮助您声明有意义的变量名。
功能
函数通常执行某种操作。为了解释这一点,人类使用动词——例如转换或显示。最好在函数名的开头使用动词,例如convertCurrency
或displayUserName
。
数组
它们通常包含一个项目列表;因此,在变量名后面加上s
。例如:
const students = ['Eddie', 'Julia', 'Nathan', 'Theresa']
布尔值
简单地从“是”或“必须”接近自然语言开始。你可以这样问,“那个人是老师吗?”→“是”或“不是”。“类似:
const isTeacher = true // OR false
数组函数
forEach
、map
、reduce
、filter
等都是很好的原生JavaScript函数,可以处理数组并执行一些操作。我看到很多人只是将el
或element
作为参数传递给回调函数。虽然这既简单又快捷,但是您也应该根据它们的值来命名它们。例如:
const cities = ['Berlin', 'San Francisco', 'Tel Aviv', 'Seoul'] cities.forEach(function(city) { ... })
id
通常,您必须跟踪特定数据集和对象的id
。当id
被嵌套时,简单地将它保留为id
。在这里,我喜欢在将对象返回到前端之前将MongoDB _id
映射为简单的id
。当从对象中提取id
时,在前面加上对象的类型。例如:
const studentId = student.id // OR const { id: studentId } = student // destructuring with renaming
该规则的一个例外是模型中的MongoDB引用。在这里,只需在引用模型之后命名该字段。这将在填充引用文档时保持清晰:
const StudentSchema = new Schema({ teacher: { type: Schema.Types.ObjectId, ref: 'Teacher', required: true, }, name: String, ... })
在可读性方面,回调是最糟糕的,尤其是在嵌套时承诺是一个很好的改进,但在我看来,async/await
具有最好的可读性即使对于初学者,或者来自其他语言的人,这也会有很大帮助。但是,要确保你理解它背后的概念,不要漫不经心地到处使用它。
正如我们在技巧1和2中看到的,保持逻辑在正确的位置是可维护性的关键同样,如何导入不同的模块可以减少文件中的混乱。导入不同模块时,我遵循一个简单的结构:
// 3rd party packages import React from 'react' import styled from 'styled-components' // Stores import Store from '~/Store' // reusable components import Button from '~/components/Button' // utility functions import { add, subtract } from '~/utils/calculate' // submodules import Intro from './Intro' import Selector from './Selector'
我在这里使用react组件作为示例,因为有更多类型的导入。你应该能够适应你的特定用例。
console.log
是调试 - 的一种很好的方法,非常简单、快速,而且可以完成任务显然,有更复杂的工具,但我认为每个开发人员仍然在使用它。如果你忘了清理日志,你的主机最终会变得一团糟。然后有一些日志实际上要保存在代码库中;例如,警告和错误。
为了解决这个问题,出于调试的原因,您仍然可以使用console.log
,但是对于持久的日志,可以使用loglevel
或winston
这样的库。另外,您可以使用ESLint警告控制台语句。这样你就可以轻松地在全球范围内寻找控制台…并删除这些语句。
遵循这些准则确实帮助我保持代码库的干净和可伸缩性。有什么特别有用的建议吗在评论中让我们知道你将在你的编码工作流程中包括什么,并且请分享你使用的任何其他技巧来帮助代码结构!
原文地址:https://blog.logrocket.com/12-tips-for-writing-clean-and-scalable-javascript-3ffe30abfe20/
In order to ensure readability, this article uses free translation rather than literal translation.
For more programming-related knowledge, please visit: Introduction to Programming! !
The above is the detailed content of 12 Tips for Writing Clean and Scalable JavaScript Code. For more information, please follow other related articles on the PHP Chinese website!