A function is a special type of object in JavaScript

1. Function definition

(1) Understand function literals

A function literal is the simplest and most straightforward way to define a function. It generally consists of four parts:

  • The keyword function
  • Function name: The function name identifies the function, but it can also be omitted
  • A set of parameters enclosed in parentheses: Parameters are defined as variables in a function that are initialized to the value actually supplied when the function is called
  • A group of statements enclosed in curly braces: Statements are the body of a function and they are executed when the function is called

(2) Define the function

Using function literals provides two ways to define functions in JavaScript:

  • Function declaration statements: Function declaration statements are simple applications of function literals, and are actually the way we define functions more often
// Define a function that computes the addition of two numbers
function add(a, b) {
    return a + b
}

// Define a recursive function that computes factorial
function factorial(x) {
    return (x <= 1)?1 : x * factorial(x - 1)}Copy the code
  • Function definition expression: In JavaScript, a function is also an object, so we can assign the function definition to a variable
// Define a function that computes the addition of two numbers. To make the code more compact, function literals omit the function name
var add = function(a, b) {
    return a + b
}

// Define a recursive function that computes the factorial. To facilitate the function calling itself, the function literal needs the function name
var factorial = function fact(x) {
    return (x <= 1)?1 : x * fact(x - 1)}Copy the code

(3) Compare the two ways of defining a function

What is the difference between the two ways of defining functions (function declaration statements and function definition expressions)?

  • Declaration time

    Function declaration statements can only appear in global code or embedded in other functions, not in statements such as conditional judgments

    Functional definition expressions can appear anywhere in the code

  • Call time

    A function defined as a function declaration statement is advanced to the top of the function scope at compile time, so it can be called before it is defined

    For function definition expressions, although the variable is declared earlier, the variable is not assigned earlier, so it can only be called after the function has been defined

2. Function calls

(1) Implicit parameters

When a function is called, each function takes two implicit arguments: this and arguments, in addition to explicitly passing in the function arguments

The value of the this parameter depends on the mode in which the function is called; The arguments can be used to get all the arguments to the function passed in

(2) Function call method and this value

There are three common ways to call JavaScript functions: function calls, method calls, and constructor calls

  • Call as a function

In the simplest case, the function is called as a normal function, in which case this is bound to the global object

> // Define a normal function
> var add = function(a, b) {
    // This is bound to the global object.
    // The value of this may vary depending on the environment in which JavaScript is being run
    return a + b
}
> // Add is called as a function, and this is bound to the global object
> Function (argument,...)
> add(1.1)
Copy the code

In fact, binding this to a global object when a function is called as a normal function is not a very sensible design

The book The Essence of JavaScript even calls this “a language design mistake” because it tends to pollute global objects

  • Called as a method

When a function exists as a property of an object, it is called a method, and this is bound to that object

> // Define a counter object
> var counter = {
    value: 0.Increment as a method (an attribute of the counter object)
    increment: function() {
        When increment is called as a method, it automatically gets an implicit argument this, referring to the object itself
        this.value += 1}} >// Increment is called as a method, and this is bound to the counter object
> Function (argument,...)
> counter.increment()
> counter.value
/ / 1
Copy the code
  • Called as a constructor

Constructors are defined in exactly the same way as normal functions, except that the naming convention for constructors begins with a capital letter

This is now bound to the new object returned by the constructor

// Define Message function as constructor
> var Message = function(descrition) {
    When the Message function is called as a constructor, it automatically gets an implicit argument, this, bound to the new object
    this.detail = descrition
}
> The Message function is called as a constructor, and this is bound to the Message object
> Argument: new Function(argument,...)
> var message = new Message('Hello')
> message.detail
// 'Hello'
Copy the code

There is a serious problem here. Imagine what would happen if we accidentally called the constructor as a normal function

This will be bound to the global object, which means that any properties we add to the new object will be added to the global object, polluting the global object

So we have to do extra work to make sure the constructor is called properly

> var Message = function(descrition) {
    // Check if this refers to the current object
    // If so, the function is called as a constructor, and you can safely initialize the object
    if (this instanceof Message) {
        this.detail = descrition
    }
    // If not, the function may have been called in the wrong way, and the constructor needs to be called again in the correct way
    else {
        return new Message(descrition)
    }
}
Copy the code

(3) Function parameters and arguments

In JavaScript, there is no requirement that the number of arguments passed in match the number of parameters specified when the function is defined, which makes some interesting things happen

  • When the number of arguments is less than the number of parameters

If the number of arguments is less than the number of parameters, the extra parameters will be set to undefined

At this point, you can set appropriate default values for the parameters passed to the function to prevent unexpected errors in the program

> function add(a ,b) {
    a = a || 0
    b = b || 0
    return a + b
}
> add(5.7)
/ / 12
> add(9)
/ / 9
> add()
/ / 0
Copy the code
  • When the number of arguments is greater than the number of parameters

If the number of arguments is greater than the number of parameters, the extra arguments are passed to the function as usual, but their references cannot be retrieved

At this point, you can use the implicitly passed argument to get all the arguments to the passed function

> function add() {
    var total = 0
    for (let curr = 0, len = arguments.length; curr < len; curr++) {
		total += arguments[curr]
    }
    return total
}
> add(1.2.3.4.5)
/ / 15
Copy the code