Explanation of the Functions and Methods of JavaScript Basic Series

  • 2021-11-13 06:30:49
  • OfStack

Directory 1. The difference between function and method 2. How to write a function 2.1. Naming accurately
2.1. 1 Function naming
2.1. 2 Parameter naming
2.2 Function Comments
2.2. 1 Parameter comments
2.3 Function parameters
2.3. 1 Default values for parameters
2.3. 2 Object parameters
2.3. 3 Number of parameters
2.3. 4 Parameter type defense
2.4 Return of the function
2.4. 1 Idempotent function
2.4. 2 Pure functions
2.4.3 return null
Summary of the difference between functions and methods

1. Differences between functions and methods

Function (function): A function is an JavaScript snippet with a name and arguments that can be defined and called multiple times at a time. Method (method): When a function and an object are written at 1, 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 function well

In JS, in addition to variables, the most used function should be, and the function is the first citizen of Javascript.

2.1 Accurate naming

2.1. 1 Function naming

The naming of functions needs to be clear, semantic and simple to summarize the functions of functions. We should not shorten the function name because the code is short, which will not improve any performance or efficiency. On the contrary, if a function name is not clear enough, others often cannot understand it.

Try to use verbs, such as getXxxxx and setXxxxx. If the verb comes first, the semantics will be clearer.

2.1. 2 Parameter naming

Emphasis is placed on semantics, and parameter naming makes it clearer for callers to know what to pass in and what parameters to correspond to. Of course, some generic names like callback and fn are acceptable. Even if I don't look at the comments, I often know what the parameters here are going to do and pass.

2.2 Function Comments


/**
 *  Time formatter 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 comments

/**
 *  Time formatter tool function 
 * 
 * @param { (Date | number) } date -  Time 
 * @param { string } unit -  Conversion format 
 */

@ param {type} Parameter-Parameter explanation: type indicates the type of parameter, such as string and number. When there are multiple parameter types, it can be identified as {(stringstring [])}, indicating that this parameter can be a string or an array of strings.

Object attributes: Every 1 attribute of the object needs to be interpreted


/**
 *  Function to assign items to employees 
 * 
 * @param {Object} employee -  Project staff 
 * @param {string} employee.name -  Name of Project Employee 
 * @param {string} employee.department -  Department of Project Employee 
 */
 Project.prototype.assign = function(employee) {
   // ...
 };

Optional parameters:


/**
 *  Time formatter 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 formatter 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 values for parameters

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 the parameters default values, so that you can pass only the first few necessary parameters and call them 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 parameter in my middle is different, I need to pass all the parameters before this parameter once. This is obviously not feasible. Therefore, when there are many parameters, we need to pass parameters by means of 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 deconstruction is that I can pass as many parameters as I want, regardless of the order. However, functions with so many parameters often have problems (specific problems are analyzed concretely). That is, the number of parameters mentioned below.

2.3. 3 Number of parameters

The fewer parameters of a function, the better, and there should be no more than three at most. More parameters often mean more relationships, and there are more logical crosses. When testing, it is often difficult to cover all conditions, and the probability of problems increases.

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

2.3. 4 Parameter type defense

Before the development of TS, we didn't know what the user would send in, which is often prone to type errors, or we want to achieve compatibility, like the previous timeFormat function, we hope that when the user calls, he can want to format the time object or the timestamp, so we need to do a defense processing.


  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 avoid the parameter type problem, but this is not absolute, because we sometimes accept the data returned by the interface directly.

We often say, never trust the user's input. Similarly, I don't believe the data returned by the interface. We can't guarantee that the back end will not go wrong. The agreed parameters are array types. Why do you give me an null when it is empty?

Of course, these situations sometimes need to be tried and wrong, and sometimes we can think of the possibility. Don't be lazy, write down the type judgment.

2.4 Return of the function

2.4. 1 Idempotent function

What is idempotent? Simply put, what is input and what is output is fixed. The input parameter determines the output parameter. No matter how many times it is called, as long as one sample is input, the result should remain one sample.


/**
 *  Time formatter tool function 
 * 
 * @param { (Date | number) } date -  Time 
 * @param { string } unit -  Conversion format 
 */
0

Idempotent functions are maintainable and relatively easy to unit test.

2.4. 2 Pure functions

Under the condition of idempotent, pure functions also require no side effects.


/**
 *  Time formatter tool function 
 * 
 * @param { (Date | number) } date -  Time 
 * @param { string } unit -  Conversion format 
 */
1

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


/**
 *  Time formatter tool function 
 * 
 * @param { (Date | number) } date -  Time 
 * @param { string } unit -  Conversion format 
 */
2

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

2.4.3 return null

null is relatively troublesome to process and needs to be judged, which leads to extra code. It should return an empty object, an empty array, or throw an exception.

Differences between functions and methods

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

2) A method (method) is an javascript function that is called through an object. That is, a method is also a function, just a special function. It is associated with an object. Assuming that one function is fn and one object is obj, you can define an method:

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

3) The data of the function is passed explicitly

4) The data in the method is passed implicitly; The method is related to the object.

Summarize


Related articles: