JavaScript Basics Series: Functions and Methods

JavaScript Basics Series: Functions and Methods

1. The difference between functions and methods

  • Function: A function is a JavaScript code snippet with a name and parameters that can be defined once and called multiple times.
  • Method: When a function and an object are written together, the function becomes a "method". For example, when a function is assigned to a property of an object, we call it a "method".

2. How to write a good function

In JS, besides variables, the most used thing is probably functions, which are the first citizens of Javascript.

2.1 Accurate naming

2.1.1 Function Naming

The function name needs to be clear, semantically clear, and simply summarize the function's functionality. We should not shorten the function name in the hope of shortening the code. This will not improve performance or efficiency. On the contrary, if a function name is not clear enough, others often cannot understand it.

Try to use verbs as much as possible, such as: getXxxxx, setXxxxx. Putting the verb in front will make the semantics clearer.

2.1.2 Parameter Naming

Emphasis on semantics, parameter naming allows the caller to know more clearly what to pass in and what parameters it corresponds to. Of course, some common names are acceptable, such as callback and fn. Even without reading the comments, I often know what the parameters here are for and what to pass.

2.2 Function Annotations

/**
 * Time formatting tool function * 
 * @param { (Date | number) } date - time * @param { string } unit - conversion format */
export const timeFormat = (date: Date | number | string, unit: string) => {
  if (!date) {
    return ''
  }
  if (typeof date === 'string') return date;
  if (typeof date === 'number') {
    date = new Date(date);
  }
  const year = date.getFullYear();
  const month = date.getMonth() + 1;
  const day = date.getDate();
  const hour = date.getHours();
  const minute = date.getMinutes();
  const second = date.getSeconds();
  if (unit === 'year') return `${year}`;
  if (unit === 'month') return `${year}-${month}`;
  if (unit === 'day') return `${year}-${month}-${day}`;
  if (unit === 'hour') return `${year}-${month}-${day} ${hour}`;
  if (unit === 'minute') return `${year}-${month}-${day} ${hour}:${minute}`;
  if (unit === 'second') return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
}

2.2.1 Parameter Annotations

/**
 * Time formatting tool function * 
 * @param { (Date | number) } date - time * @param { string } unit - conversion format */

@param { type } parameter - parameter explanation: type indicates the type of the parameter, such as string, number. When there are multiple parameter types, they can be marked as { (string|string[]) }, indicating that this parameter can be a string or a string array.

Object properties: Each property of the object needs to be explained

/**
 * Function to assign projects to employees * 
 * @param {Object} employee - project employee * @param {string} employee.name - name of project employee * @param {string} employee.department - department of project employee */
 Project.prototype.assign = function(employee) {
   // ...
 };

Optional parameters:

/**
 * Time formatting tool function * 
 * @param { (Date | number | string) } date - time * @param { string } [unit] - conversion format */
export const timeFormat = (date: Date | number | string, unit: string) => {
  // ...
}

default value:

/**
 * Time formatting tool function * 
 * @param { (Date | number) } date - time * @param { string } [unit = 'second'] - conversion format */
export const timeFormat = (date: Date | number | string, unit = 'second') => {
  // ...
}

2.3 Function Parameters

2.3.1 Default Parameter Values

export const timeFormat = (date: Date, unit = 'second') => {
  // ...
}

2.3.2 Object Parameters

async function printer_proxy_print(
  html_str: string,
  file_path: string,
  device: string | undefined,
  orientation: number,
  printer_mode: string,
  width: number,
  height: number,
  scale: number,
  from: number,
  to: number,
  left_offset: number,
  top_offset: number,
  pdf_tools: string | undefined,
  begin_page = 1,
  end_page = 1,
  repeat_times = 1,
  print_type: string
) {
    // ...
}

You can give default values ​​to parameters so that you can pass only the first few necessary parameters, like this.

async function printer_proxy_print(
  html_str: string,
  file_path: string,
  device = 'pc',
  orientation = 'xxx',
  printer_mode = 'xxx',
  width = 123,
  height = 123,
  scale = 123,
  from = 123,
  to = 123,
  left_offset = 123,
  top_offset = 123,
  pdf_tools = 123,
  begin_page = 1,
  end_page = 1,
  repeat_times = 1,
  print_type = 'base64'
) {
    // ...
}

await printer_proxy_print(html_str, file_path);

The above method seems feasible. In fact, when a certain parameter in the middle is different, I need to pass all the parameters before this parameter again. This is obviously not feasible. So when there are many parameters, we need to pass them by object deconstruction.

async function printer_proxy_print({
  html_str,
  file_path,
  device = 'pc',
  orientation = 'xxx',
  printer_mode = 'xxx',
  width = 123,
  height = 123,
  scale = 123,
  from = 123,
  to = 123,
  left_offset = 123,
  top_offset = 123,
  pdf_tools = 123,
  begin_page = 1,
  end_page = 1,
  repeat_times = 1,
  print_type = 'base64'
}) {
    // ...
}

await printer_proxy_print({html_str, file_path});

The advantage of destructuring is that I can pass any number of parameters I want without worrying about the order. However, functions with so many parameters often have problems (specific problems require specific analysis). That is the problem of the number of parameters mentioned below.

2.3.3 Number of parameters

The fewer parameters a function has, the better. It should not exceed 3 at most. More parameters often mean more relationships and more logical intersections. When conducting tests, it is often difficult to cover all conditions, and the probability of problems increases.

When there are many parameters, it sometimes also means many functions, which violates the principle of single function.

2.3.4 Parameter Type Defense

Before TS development, we don't know what the user will pass in, which often leads to type errors. Or, we want to achieve compatibility, such as the previous timeFormat function. We hope that when the user calls it, they may want to format the time object or the timestamp. In this case, we need to do a defensive process.

  if (!date) {
    return ''
  }
  if (typeof date === 'string') return date;
  if (typeof date === 'number') {
    date = new Date(date);
  }

However, it is worth noting that even if we use TS, in most cases we can indeed avoid parameter type problems, but this is not absolute, because sometimes we directly accept the data returned by the interface.

We often say that we should never trust user input. Similarly, I don’t trust the data returned by the interface. We cannot guarantee that the backend will not make mistakes. The agreed parameter is of array type. How come you give me null when it is empty?

Of course, these situations sometimes require trial and error, and sometimes we can think of the possibilities, so don't be lazy and write down the type judgment.

2.4 Function Return

2.4.1 Idempotent Functions

What is idempotence? Simply put, the input and output are fixed. The input parameters determine the output parameters. No matter how many times it is called, as long as the input is the same, the result should remain the same.

  function sum(a: number, b: number) {
    return a + b;
  }

Idempotent functions are maintainable and relatively easy to unit test.

2.4.2 Pure functions

Pure functions are required to have no side effects in addition to being idempotent.

  const dog = {
    name: 'puppy',
    age: 2,
    weight: 30,
  }

  if (!dog.color) {
    console.log('has no color');
  }

  function addColor(dog) {
    dog.color = 'white';
  }

  addColor(dog);
  console.log(dog); // {name: "puppy", age: 2, weight: 30, color: "white"}

As you can see, the addColor function modifies the properties of the dog object, which means it has a side effect.

  function addColor(dog) {
    let copyDog = Object.assign({}, dog);
    copyDog.color = 'white';
    return copyDog;
  }

In this way, the properties of the dog object will not be modified and the addColor function is a pure function.

2.4.3 return null

Null is relatively troublesome to process, and requires judgment, resulting in additional code. It should return a null object, an empty array, or throw an exception.

Difference between function and method

1) A function is a piece of code that is called by name. It can pass some data (parameters) in for processing, and then return some data (return value), or it can have no return value.

2) A method is a JavaScript function that is called through an object. In other words, methods are also functions, just special ones. It is associated with an object. Assuming there is a function fn and an object obj, you can define a method:

obj.method = fn;
obj.method();

3) Function data is passed explicitly

4) Data in methods is passed implicitly; methods are related to objects.

Summarize

This concludes this article on JavaScript Basics Series: Functions and Methods. For more information on JavaScript functions and methods, please search previous articles on 123WORDPRESS.COM or continue browsing the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of this pointing in JS arrow function
  • JavaScript function syntax explained
  • Detailed explanation of the use of Vue.js render function
  • JavaScript function call, apply and bind method case study
  • JavaScript CollectGarbage Function Example
  • Detailed explanation of JavaScript function introduction

<<:  MySQL table auto-increment id overflow fault review solution

>>:  Implementation of k8s deployment of docker container

Recommend

Using Docker run options to override settings in the Dockerfile

Usually, we first define the Dockerfile file, and...

VSCode+CMake+Clang+GCC environment construction tutorial under win10

I plan to use C/C++ to implement basic data struc...

VUE + OPENLAYERS achieves real-time positioning function

Table of contents Preface 1. Define label style 2...

HTML table tag tutorial (44): table header tag

<br />In order to clearly distinguish the ta...

Detailed example of SpringBoot+nginx to achieve resource upload function

Recently, I have been learning to use nginx to pl...

How to install common components (mysql, redis) in Docker

Docker installs mysql docker search mysql Search ...

Teach you how to build hive3.1.2 on Tencent Cloud

Environment Preparation Before starting any opera...

Implementing access control and connection restriction based on Nginx

Preface Nginx 's built-in module supports lim...

Example of removing json backslash in php

1. Remove backslashes through the "stripslas...

Detailed explanation of Linux text processing tools

1. Count the number of users whose default shell ...

An in-depth introduction to React refs

1. What is Refs is called Resilient File System (...

How to set static IP in CentOS7 on VirtualBox6 and what to note

Install CentOS 7 after installing VirtualBox. I w...

Detailed explanation of the solution for migrating antd+react projects to vite

Antd+react+webpack is often the standard combinat...

A brief discussion on several specifications of JS front-end modularization

Table of contents Preface The value of front-end ...