★★★★✰

An overview of the

If you think of code as articles, classes are nouns and functions are verbs, and a good function definition makes your program vivid and clear, helping you tell the story. So how do you write a good function?

1. Short

In the 1980s, we used to say functions shouldn’t be longer than one screen. At the time of this remark, the VT100 screen had only 24 rows and 80 columns. In JAVA object-oriented languages, good functions are usually only three or four lines long. The same can be done with JS Class writing and TypeScript. What we can do is keep it short, make sure that a function only says one thing.

Code blocks and indentation

Generally, code indentation does not exceed 2 levels at most.

bad

// Multiple levels of judgment indentation like this, once filled with complex code, can be very verbose and difficult to read
if () {
	if () {
		for () {
			if()}}}Copy the code

good

// It is possible to disassemble multiple levels
if () {
	doSmthing()
} else {
	doElseThing()
}
Copy the code

2. Do only one thing

The function should do one thing, do it well, only do one thing. (Important things say three times)

Another way to determine if a function does more than one thing is to see if it can split out a function that does more than simply reinterpret its implementation.

For example, if your function contains the following actions:

(1) Dom node construction

(2) Find the target container

(3) Render HTML

(4) Handle the successful callback event

So you can think about splitting it up into multiple functions.

good

function() {
	1 / / function
	const createdDom = generateDom()
	/ / function 2
	const targetContainer = findContainerByClause()
	3 / / function
	targetContainer.insert(creataedDom).then(() = > {
		/ / function 4
		successCallback()
	})
}
Copy the code

3. One layer of abstraction per function

What is done in a function should be at the same level of abstraction.

For example, the same function does not belong to the same hierarchy if it has the following actions:

1) Render the entire HTML page

2) Generate HTML header nodes

2) Add a DOM element

bad

// The three functions are not at the same level of abstraction (render the page, create the page header, add a div)
function() {
	renderPage()
	createHeaderHtml()
	header.appendNode('<div>text</div>')}Copy the code

good

function() {
	renderPage()
}

renderPage() {
	createHeaderHtml()
	createFooterHtml()
}

createHeaderHtml() {
	header.appendNode('<div>text</div>')
	header.appendNode('<div><button></div>')}Copy the code
Down the rules

The abstraction level of functions is top-down.

For example: Assemble the car > assemble the engine > assemble the screws

4. Use descriptive names

Don’t be afraid of long names. Long, descriptive names are better than short, confusing ones.

Try to keep the style consistent.

Such as:

Create a node using the same prefix rules as createHeader and createFooter.

Don’t have createHeader, don’t have insertFooter.

5. Function parameters

As few parameters as possible

Parameter Number: 0 > 1 > 2 > 3+

If there are too many arguments, consider encapsulating the object or promoting it to public variables

bad

makeCircle(x, y, radius, color, borderColor)
Copy the code

good

Point = {
	x, y, color, borderColor
}

makeCircle(Point center, radius)
Copy the code
Identification parameter

Identifiers are ugly and are a loud declaration that this function does more than one thing.

bad

function() {
	const isVueTemplate = getTempalteType()
	render(isVueTemplate)
}
Copy the code

good

function() {
	const isVueTemplate = getTempalteType()
	if (isVueTemplate) {
		renderVue()
	} else {
		renderReact()
	}
}
Copy the code

6. No side effects

Unexpected modification

bad

// Validate user input
validateInput(password, username) {
	const valid = checkRegax(password, username)
	// Resetting the form is not a validation of user input
	if(! valid) { resetForm() }return valid
}
Copy the code
Output parameters

Arguments are most naturally thought of as inputs to a function, and it can be somewhat confusing if your arguments are output rather than input.

The following setUserIndex method is the case

function() {
	const userList = getUserList()
	setUserIndex(userList)
	userList...
}

setUserIndex(userList) {
	userList.map((item, index) = > {
		item.index += 1
		return item
	})
}
Copy the code

7. Distinguish between instructions and judgments

Mixing instructions and judgments into a function can be confusing.

For example, the following function is used to: 1. Set the user name, 2. Check whether the user already exists

bad

// The reason for this if failure is somewhat confusing
if (setUsername('wang')) {}
Copy the code

good

if (nameNotExists('wang')) {
	setUsername('wang')}Copy the code

8. Use exceptions instead of error codes

In order to make the code structure clearer and easier to understand, you can use exceptions instead of handling all kinds of bad code. Ajax or Axios are good examples.

ajax.post.then(() = > {

}).catch((err) = >{})Copy the code

9. Don’t repeat yourself

If something in a function is repeated more than once, consider extracting it.

10. How to optimize functions

I don’t think anyone could write a function from the start. So how do you optimize?

Put in unit tests that cover every line of code, and then polish that code, breaking up functions, changing names, eliminating duplication.

This article is based on Code Cleanliness by Robert C. Martin, translated by Han Lei.

Zhejiang Dahua Technology Co., Ltd.- Soft research – Smart City Product R&D Department Recruiting senior front end, welcome to contact, interested can send resume to [email protected], long-term effective

Previous article: “Two, meaningful naming”

Next chapter: iv. Notes