7, functions,

Functions are actually objects; each Function is an instance of type Function, and the Function name is a pointer to the Function object

Simply put, a function is an object, which encapsulates a block of code that can be repeatedly called and executed. By calling a function, we can realize a large number of code repetitions

7.1 Defining Functions

There are four ways to define a function:

  1. Function declaration
  2. Functional expression
  3. Arrow function (ES6)
  4. FunctionThe constructor

1. Function declaration

Function declarations are the most common way we define functions

function foo() {
	console.log("Hello world!")}Copy the code

2. Function expressions

Function expressions are almost equivalent to function declarations

var foo = function() {
	console.log("Hello world!")}Copy the code

This is the same as variable initialization

Function expressions differ from function declarations in that they do not promote variables

3,FunctionThe constructor

let foo = new Function(console.log("Hello world!"));
Copy the code

This method of defining functions is not recommended because the code will be executed twice:

  • First time: Execute it as regular code
  • The second: parses the string passed to the constructor

4. Arrow function

Arrow functions are known for being short and snappy, similar to function expressions

let foo = (sum1, sum2) = > { console.log(sum1 + sum2) }
Copy the code

New the ES6

7.2 Function Parameters

Function parameters include parameters and arguments

  • Parameter: When defining a function, define the variables used by the function
  • Argument: Data passed to a function when it is called

However, unlike other languages, JS functions do not care about the number of arguments you pass in. Even if you define a function to accept two parameters, it does not mean that you need to pass in two arguments to call the function

You can pass in one, two, three, or none at all, and the interpreter will not report an error, and no one will say you; Is not surprised to drop jaw!

Let’s take a look:

function foo(a, b) {
    console.log(a + b); }; Foo ();// NaN
foo(1);// NaN
foo(1.2.3);/ / 3
Copy the code

Why is that?

1.argumentsobject

Who are the arguments?

Arguments is an object and is a pseudo-array object. The pseudo-array is not an instance of Array

So what does it do? Arguments are stored in the order that arguments are passed in, so the first argument is 0 and the second argument is 1

Arguments is a pseudo-array that stores arguments passed in

So, when using functions defined by the function keyword, we can access the arguments object to get the arguments passed in

It must be a function defined by the function keyword, not an arrow function because arrow functions cannot use arguments

Let’s get a feel for it:

function foo(a, b) {
    console.log(arguments[0] + arguments[1]);
}
foo(10.20);  / / 30
Copy the code

We can also see how many arguments there are in Arguments

function foo(a, b) {
	console.log(typeof arguments);
    console.log(arguments.length);
    console.log(arguments);
}
foo(10.20);
// object
/ / 2
// {'0': 10, '1': 20}
Copy the code

Now can you explain why the parameters are passed without error

  • When we pass less or no pass,argumentsSo what I’m pulling out is actually going to beundefined.undefinedIt returns when it adds itself or when it adds with numbersNaN
  • When we multipass, the JS interpreter only takes what it needs and sets aside what it doesn’t

So, the parameters of the JS function are just written for convenience, so that you don’t have to bother writingarguments[0],arguments[1]. , so arguments don’t have to be written

2. Default parameter values

The default parameter value is the number we can set to a function parameter. When we pass a parameter, the function uses the parameter we passed, otherwise it uses the default parameter

Before ES6, we all needed to check for passing parameters and use default parameters if not

// When no parameter is passed, the type of b is undefined
function foo(a, b) {
    b = (typeofb ! = ='undefined')? b :20
    console.log(a + b);
}
foo(10);  / / 30
Copy the code

Explicit default parameters are supported after ES6

function foo(a, b=20) {
    console.log(a + b);
}
foo(10);  / / 30
Copy the code

Now we define the default parameters explicitly

Note that when using default parameters,argumentsThe value of the object does not reflect the default value of the argument, only the argument passed to the function

Arrow functions can also use default arguments

7.3 Return Value of a Function

1.returnstatements

Our function only implements the function, and the final result needs to be returned to the caller of the function (), which can be achieved by return

function share() {
    return "I'll share as long as you're here.";
}
share();  // Execute the function (print the output)
Copy the code

We can also assign the function name share to another variable

var foo = share;
Copy the code
  • nowfooThat’s the name of the function

Note: Using a function name without parentheses only accesses the function pointer, not executes the function; Both foo and share point to the same function


Practice:

/ / a practice
function getMax(a, b) {
    if (a > b) {
        return a
    } else {
        return b
    }
}
console.log(getMax(10.20));  / / 20


// Exercise 2: Use ternary expressions
function getMax1(a, b) {
    return a > b ? a : b
}
console.log(getMax1(10.20));  / / 20
Copy the code

2,returnThe end of the function

The return function also acts as a termination statement, meaning that nothing after the return statement is executed

function share() {
    return 'As long as you are here I will always share! '
    alert('Of course! ');   // Will not be executed
}
console.log(share());  As long as you are here, I will always share!
Copy the code

3,returnThe return value

A return statement can return only one value

function getNum(a, b) {
	return a, b;
}
console.log(getNum(10.20));  / / 10
Copy the code

4. Function if noreturn

If the function does not return, it returns undefined

function foo(a) {+; };console.log(foo(10));  // undefined
Copy the code

The difference between break, continue, return

function instructions Main target
break End the current loop body (e.gfor,while) cycle
continue Jump out of the loop and continue with the next loop (e.gfor,while) cycle
return You can not only exit the loop, you can also returnreturnStatement, and can also end the program inside the current function Loop, function

7.4 Function Invocation

Functions can be called in several ways:

  • Regular call
  • Called by another function
  • Immediately call

1. General calls

A normal call is when we define our own function and call it ourselves

function share() {
    return "I'll share as long as you're here.";
}
share();  // Call the function
Copy the code

This is perfectly normal

2. Called by another function

You call yourself through some other function

function foo1() {
    console.log(10)}function foo() {
    console.log(20)
    foo1();
}
foo()  // Execute two functions at once
Copy the code

Many times, however, functions are passed as values into other functions

In JS, function names are variables, so functions can be used wherever variables can be used. This means that you can not only return a function from one function but also pass the function as an argument to another function

Define a function:

function add(a) {
    return a + 20
}
Copy the code

Pass this function as an argument to another function:

// The first argument is the function passed in, and the second argument is the value of the function passed in
function callAdd(callback, num) {
    return callback(num)
}

var result = callAdd(add, 10)
console.log(result);  / / 30
Copy the code
  • The abovecallAddFunction is for accesscallbackFunction, not calling it, so no parentheses
  • This approach is often used in callback functions

Execute the function immediately

We usually define functions that need to be called by ourselves, but there is one kind of function that executes itself: execute the function immediately

Executing a function immediately is also called calling a function expression immediately (IIFE)

IIFE is interpreted as a function expression because it is enclosed in parentheses

(function() {function body})()Copy the code

Simple chestnuts:

(function() {
    console.log('Hello world! '); }) ();// Hello world!
Copy the code

Parentheses can also pass arguments:

(function(a, b) {
    console.log(a + b); }) (10.20);  / / 30
Copy the code

Immediate functions were useful before ES6, when block-level scope was not supported. In the days of VAR, iterating variable I declared using the var keyword was not restricted to the block-level scope of the for loop

for (var i = 0; i < 5; i++) {}
console.log(i);  / / 5
Copy the code

External access to block-level variables is never allowed, so IIFE comes to the rescue

(function() {
    for (var i = 0; i < 5; i++) {}
})()
console.log(i);  / / an error
Copy the code

Defining loops in IIFE prevents variable definitions from leaking out; As soon as the function completes, its chain of action is destroyed

However, after ES6, when the let declaration keyword was born, block-level scoped variables were locked

for (let i = 0; i < 5; i++) {}
console.log(i); / / an error
Copy the code
  • So, you don’t have to use it nowIIFEthe

7.5 Private Variables

Any variables defined in a function are private and cannot be accessed externally

function foo() {
    let num = 10;
}
foo();
console.log(num);  / / an error
Copy the code
  • No matter usevarorletAll declared variables are private

There are also ways to access variables inside functions, which involves another thing: closures; We’ll talk about that later

7.6 Recursive functions

A recursive function is a function that calls itself by name

We can use recursive thinking when we calculate 1 * 2 * 3 * 4 * 5:

function factorial(num) {
    if (num === 1) {
        return num
    }
    return num * factorial(num - 1);
};
let sum = factorial(5);
console.log(sum); / / 120
Copy the code

The operation process is as follows:

retrun 5 * factorial(4);  / / for the first time
retrun 5 * (4 * factorial(3));  / / the second time
retrun 5 * (4 * (3 * factorial(2)));  / / the third time
retrun 5 * (4 * (3 * (2 * factorial(1))));  / / for the fourth time
retrun 5 * (4 * (3 * (2 * (1))));  / / for the fifth time
Copy the code

Note: An error occurs when we assign a function to another variable and set factorial to null

let anotherF = factorial;
factorial = null
console.log(anotherF(5)); / / an error
Copy the code

This is because anotherF retains a reference to the function, which calls factorial recursively, but factorial is no longer a function, so an error will be reported

We can create a named function expression, f(), and then it will assign factorial, so that even if we assign the function to some other variable, no assignment will affect the new variable to call the function, because it recursively calls f(), and f doesn’t change, okay

let factorial = function f(num) {
    if (num === 1) {
        return num
    }
    return num * f(num - 1);
};

let anotherF = factorial;
factorial = null
console.log(anotherF(5)); / / 120
Copy the code

Let’s do another one: Print Fibonacci numbers

Fibonacci sequence: The first two numbers are 1 and each subsequent number is the sum of the first two numbers (e.g. 1, 1, 2, 3, 5, 8, 13…).

// Encapsulates a function of the Fibonacci sequence
let factorial = function f(num) {
    if (num <= 2) {
        return 1
    }
    return f(num - 1) + f(num - 2)};// Prints the first 10 digits
var arr = []
for (var i = 1; i <= 10; i++) {
    arr.push(factorial(i))
}
console.log(arr);  // [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
Copy the code