[Front-end JS interaction articles] function, parameter, return value, closure function, recursive function, memory, modular programming

1. Function declaration and call

1.1 Function overview

Functions can encapsulate some functions and can be used for external de-duplicated calls. Therefore, generally we call functions a code block with repeated functions.

JavaScript Basics to Advanced
Canvas Game Development
Native JavaScipt Case Collection
JavaScript + DOM Basics

Assuming that a restaurant is a function, the function of a restaurant is to cook a variety of dishes, but the specific dish needs to be ordered by the user. The user can be any of us. When we order and pay the bill, then the restaurant Just use its cooking function and start to cook the designated delicious meals for us. The process of our ordering is actually similar to the process of function calling. Finally, the restaurant presents the dish to us after cooking. This dish is similar to the data returned by the function

1.2 Declaration of function

Functions are declared using the keyword function

Inside the declared function, we can write some code to make this function have a specific function. The code written inside the function is traditionally called the function body.

Syntax format of function declaration:

function 函数名(形式参数){
	函数体
}

Thinking : find the sum of any two numbers

Naming rules for function names: Same as variable naming rules

1.3 Function call

After the function is declared, it will not be executed automatically and needs to be called

Syntax for function calls function-name()

How to call the function

  • Call the function name() directly at any point in the JS script
  • event driven

Exercise: Wrap the process statement with a function, that is, treat the process statement as a function body. For an integer greater than 0, print all its divisors.

Analysis: The smallest divisor of a number is 1, and the largest divisor is itself. If there are other divisors, it must be between 1 and itself.

What is an approximation?

Approximate numbers, also known as factors. If the quotient obtained by dividing an integer a by an integer b (b≠0) is exactly an integer without a remainder, we say that a is divisible by b, or b is divisible by a. a is called a multiple of b, and b is called a divisor of a.

Using function encapsulation, briefly introduce several benefits:

  • Avoid pollution of global variables;
  • Save memory;
  • Improve program performance;
  • Reduce the writing of repetitive code;
  • Ease of later maintenance;
  • Data can be returned for secondary operations;
    etc...

1.4 Types of functions

function f(){}
console.log(typeof f);//function

Second, the parameters of the function

2.1 The concept of function parameters

The parameter can be similarly regarded as the variable we declared before, except that its position is in the parentheses after the function, and there is no need to use var to declare it. Function parameters are divided into two types: formal parameters and actual parameters.

**Formal parameters: **Referred to as formal parameters. When the function is declared, the parameters given in parentheses, at this time, the data type and specific value of the parameters cannot be determined. Similar to the menu given to us by the waiter in the restaurant mentioned earlier, so many dishes can be provided, but the specific dishes need to be specified by the customer.

** Actual parameters: **Referred to as actual parameters. When the function is called, it is used to replace the specific value of the formal parameter (passed parameter), and the data type and value are determined at this time.

Similar to the above-mentioned ordering in a restaurant, according to the menu provided by the waiter, order the specific name of the dish

**Passing parameters: **Function calls, there is a process of passing parameters, this process we call it passing parameters.

Requirements : find an integer greater than 0, the number of divisors

Through the above description and demonstration, another feature of JS is summarized:

​JS is a dynamic, weakly typed language.

2.2 Function overloading

Overloading can be seen as the application of function parameters.

Function overloading: In a program, multiple functions with the same name are declared, but their data types and number of parameters are different.

The concept of function overloading does not exist in JS, we can only simulate it. Because once multiple functions with the same name are declared in JS, the latter will overwrite the former.

2.3 arguments object

The arguments object is a special object in JS. It is a class array, which stores all the actual parameters passed when the function is called.

A length property is built into the arguments object, which is used to obtain the number of parameters actually passed when the function is called Syntax arguments.length

Both the class array and the array have an index, and the index starts from 0 and increases sequentially, as shown in the figure above: in the arguments object, there are corresponding indexes, which correspond to the passed parameters one by one. The corresponding parameter value of the execution can be obtained through arguments[index] :

​ Get the first parameter arguments[0]

​ Get the last parameter arguments[arguments.length - 1]

function sum() {
    console.log("arguments:",arguments);
    console.log("函数调用时传递的第一个参数:",arguments[0]);
    console.log("函数调用时传递的参数个数:",arguments.length);
    console.log("函数调用时传递的最后一个参数:",arguments[arguments.length - 1]);
}

mock function overloading

3. The return value of the function

In many cases, the purpose of our encapsulation function is to use this function of the function to obtain some data, and then perform secondary operations on these data.

Then, if you want to return these data in the function, you need to use the keyword return.

The return keyword is used to return data in a function, and to jump out of a function.

If it is just to jump out of the function and does not need to return any data, then just return directly.

Exercise: Determine whether a number greater than 0 is a prime number.

What are prime numbers?

​A prime number is also called a prime number, which refers to a natural number that has no other factors except 1 and itself among the natural numbers greater than 1.

Analysis: According to the number of divisors, when the number of divisors is 2, then this number is a prime number.

return is used as a jump out function. Generally, I am often asked during interviews, what is the difference between return, break, and continue?

Fourth, the scope of the function

4.1 Scope Overview

**Overview:** When a function is declared, an independent internal area is formed inside the function (the position of the function body in curly braces). This internal area is called the function scope.

Compared with the entire script area, the function scope is just a small independent area. We usually call this small area local scope. And the entire script area, we usually call it the global scope.

Global scope : The area outside the function is called the global scope; variables declared in the global scope can be called anywhere in the script (inside the wrapper function), and this variable is called a global variable . Life cycle of global variables: created when the file is executed (currently the page is loaded), and destroyed after the page is closed.

Local scope : The area within the function is called the local scope; variables declared in the local scope can only be accessed and called inside the function, so we call them local variables at this time . The life cycle of local variables: created when the function is called, and destroyed after the function is called.

4.2 Scope chain issues:

In a nested function , there are multiple declared functions with the same name. When calling, first check whether the variable exists in the current scope, call it if it exists, and search it in the upper level scope if it does not, and use it if it exists. If not, keep looking up until you find it

//声明一个全局变量 num
var num = 1;
function fn() {
    //在第一层函数中,声明一个变量 num
    var num = 10;
    //在第一层函数中,声明一个内部函数 fn2
    //创建函数的另外一个方式  将声明的匿名函数赋值给一个变量
    var fn2 = function () {
        var num = 100;
        return num;
    }
    return fn2;
}

4.3 Variables declared without var in local scope

If you do not use var declaration inside the function, first of all, this is a non-standard way of writing, which is generally not recommended, and an error will be reported if you touch it strictly. Second, if we accidentally use it this way, this variable will be promoted to a global variable after the function is called. If the function is not called, this variable will not be created.

function f() {
    num = 10;
    console.log("num:",num);
}

In this case, the container may cause global variable pollution, so it is not recommended to use it.

var i = 2;
console.log('i:',i);//i: 2
function f1() {
    var i = 20;
    console.log('i:',i);//i: 20
}
f1();
console.log('i:',i);//i: 2

var j = 3;
console.log("j:",j);//j:3
function f2() {
    j = 30;
    console.log("j:",j);//j:30
}
f2();
console.log("j:",j);//j:30

The above j itself is intended to be treated as a local variable, but because the var declaration is not used, when the function is called, the variable that should be defined as a local variable becomes the assignment operation of the global variable, which causes the global variable Pollution, or naming conflicts.

4.4 Multiple declarations of the same variable

If a variable is declared multiple times in the same scope, the declaration will only take effect once, and the first declaration shall prevail. Subsequent declarations will not be counted, and will be directly used as variable assignment operations.

var num = 1;
console.log("num:",num);//num:1

var num = 10;
console.log("num:",num);//num:10

num = 100;
console.log("num:",num);//num:100

5. Function improvement

In JS, variables and functions are promoted. When the JS engine parses the code, it is divided into two steps:

  1. Pre-parsing phase: Promote all variable and function declarations to the top of the current scope
  2. Run phase: assign values ​​to variables

In JS, there are three ways to create functions:

  • The first standard way function function name (parameter list) {function body}

    function f() {
        num = 10;
        return "num:"+num;
    }
    
  • The second way of function expression: assign an anonymous function to a variable var f = function (parameter list) {function body}

    var f1 = function(){
        num = 10;
        return "num:"+num;
    }
    
  • The third way of built-in objects var f = new Function("parameter list", "function body")

    var f3 = new Function("num = 10; return 'num:'+num");
    
    var f2 = new Function("a","b","return a+b");
    

Functions created using the standard method are different from the other two methods when called:

  1. If they are all declared first, and then called, there is no difference: it has been verified above that f() f1() f3() results are consistent

  2. If it is called first and then declared, the result will be different, as shown in the following code

    The non-standard way is to use a variable to receive a function, so its essence is a variable. As mentioned earlier, the promotion of variables is equivalent to raising the variable declaration to the top of the current scope. At this time, no value has been assigned. When calling, the value of the variable is undefined. Therefore, the latter two methods of creating functions can only be declared first and then called.

    **Standard way: **The whole will be regarded as a declaration part, and in the pre-parsing stage, it will be raised to the top of the current scope as a whole, so the function created in the standard way can be called at any point in the current scope .

Small problem : If there are variables and functions with the same name in the same file, the function is promoted prior to the variable; as mentioned earlier, in a file, if multiple variables are declared, only the first one will take effect, and the function can also be seen As a variable, whether you use var or function, it is called a declaration. Therefore, after the function is promoted prior to the variable, the declaration of other variables becomes an assignment operation.

6. Modular programming

Suppose there is a hotel: there are security guards in the hotel responsible for security, the front desk is responsible for reception, waiters are responsible for providing services, chefs are responsible for cooking, lobby managers are responsible for coordination, and so on.

At this time, if the work of security, front desk, waiter, chef, coordination, etc. is all handed over to the lobby manager, the efficiency will be very slow, and the hotel will definitely close down in almost no time. At this time, all the functions provided by the hotel are provided by the lobby manager alone, which is definitely not possible.

At this time, considering the business problems, the hotel recruited security guards, front desk personnel, etc. to be responsible for their own work in the corresponding field, and then the lobby manager only needs to deploy these people. This effect will be very high.

Then, the same is true in the code, reducing the coupling of the code as much as possible. We can use functions to encapsulate functions as single as possible. In different scenarios, they can be reused, optimizing the code and improving the execution effect. These are actually modular ideas.

Later, as the course progresses, we will come into contact with seajs, requirejs, and nodejs, all of which are used for modular development. The difference is that it uses a js file as a module to avoid global variable pollution.

Here, we use functions to experience the idea of ​​modular programming.

From ancient times to the present, human beings have been accustomed to dividing things and making some content into some public modules, which can be used repeatedly.
Modular programming: Encapsulate some basic public parts into a function, which can be called multiple times.

**Case:** Output prime numbers within 100, modular programming.
The process of reverse thinking: Output the prime number within 100 → judge whether it is a prime number → find the approximate number

Exercise : Find the perfect number within 100: (the sum of the divisors of a number except itself is equal to this number).
Note: Modular programming can make our program more optimized. Each small module should have a single function as much as possible to increase the reuse rate.

**Exercise:** The winning number is a special natural number, except itself, and the sum of all divisors is greater than itself. Please output all winning numbers within 100

Exercise : If the sum of all divisors of an integer A (including 1, excluding A itself) is equal to B, and the sum of all divisors of an integer B (including 1, excluding B itself) is equal to A, then the integers A and B are called is a pair of close numbers. Output the intimacy number within 1000.

7. Homework

  1. Encapsulate a function to realize the function: exchange two integers without using temporary variables.

    Tip: Operators, functions have two parameters

  2. Encapsulate a function to find the maximum of 3 numbers

    Tip: The function has three parameters, and at least two methods are required to implement it

  3. Encapsulate a function to output all prime numbers between 100 and 1000 on the page, and require each line to display 6 numbers

  4. Encapsulate a function to achieve 12! - 10! results

    Requirements: Cannot use recursion

Eight, the location of the data type in memory

There are two types of data types: primitive data types and reference data types

  • Basic data type: Number value type string string type Boolean Boolean type Null empty type Undefined is not defined
  • Reference data type: Object object type, Function function type

Basic data types are stored on the stack in memory, and reference data types are stored on the heap

Code demo:

 var a = 10,
    b = 20,
    c = 30,
    fn = function () {};

console.log("a:",a,"b:",b,"c:",c,"fn:",fn);//a: 10 b: 20 c: 30 fn: ƒ () {}

//修改b的值
b = 200;
console.log("a:",a,"b:",b,"c:",c,"fn:",fn);//a: 10 b: 200 c: 30 fn: ƒ () {}

//声明一个变量d来接收基本数据类型的变量c
 var d = c;
 console.log("c:",c,"d:",d);//c: 30 d: 30

 //改变基本数据类型c的值
 c = 300;
 console.log("c:",c,"d:",d);//c: 300 d: 30
//总结:基本数据类型变量在进行赋值时,只是将变量保存的值复制了一份给另外一个变量进行赋值。此时变量值得改变不会互相影响。

//声明一个变量,来接收引用数据类型得变量
var fn2 = fn;
console.log("fn:",fn,"fn2:",fn2);//fn: ƒ () {} fn2: ƒ () {}
console.log(fn === fn2);//true 指向同一个内存地址

//改变其中一个引用数据类型的结构
fn.x = 100;
console.log("fn:",fn,"fn2:",fn2);//fn: ƒ () {} fn2: ƒ () {}
console.log(fn === fn2);//true 指向同一个内存地址
console.log("fn.x:",fn.x,"fn2.x:",fn2.x);//fn.x: 100 fn2.x: 100
//总结:引用数据类型变量在进行赋值时,将引用数据类型的变量保存的地址复制了一份给另外一个变量复制。此时两个变量指向同一个地址,其中一个结构发生改变会影响另外一个

Nine, recursive function

Recursion is calling the function itself inside the function;

Recursive functions are mostly used to solve some mathematical problems with numbers above 0 ;

A recursive function must be given a condition to exit the function, otherwise it will cause memory stack overflow.

like:

​ Cumulative question 1 + 2 + 3 + ... + 98 + 99 + 100

​ Multiplication problem 100! = 100 * 99 * 98 * ... * 3 * 2 * 1

​ The problem of giving birth to rabbits. There is a pair of rabbits, and a pair of rabbits will be born every month starting from three months. When the pair of rabbits grow to three months, they will also give birth to a pair of rabbits every month. , how many pairs of rabbits are there in total without dying?

​ Converted into mathematics, it is a Fibonacci sequence 1 1 2 3 5 8 13 21 34 55 89 144...

// 斐波那契数列  1  1  2  3  5  8  13  21  34  55 89  144...
console.log(feiBo(1));
console.log(feiBo(2));

console.log(feiBo(11));
console.log(feiBo(12));
// 求斐波那契数列中第 N 项的值
function feiBo(n) {
    if(n === 1 || n === 2){
        return 1;
    }
    return feiBo(n - 1) + feiBo(n - 2);
}

//feiBo(3) =  feiBo(3 - 1) + feiBo(3 - 2) = feiBo(2) + feiBo(1) = 1 + 1 = 2
//feiBo(4) =  feiBo(4 - 1) + feiBo(4 - 2) = feiBo(3) + feiBo(2) =  feiBo(3 - 1) + feiBo(3 - 2) + 1 = 1 + 1 + 1 = 3
//feiBo(5) = ....

10. Anonymous functions and self-executing functions

Anonymous function: also called lambda function, to put it bluntly, it is a function without a name

Self-executing function: IIFE, also called immediately executing function. There is no need to call it, it will be called automatically with the execution of the program. IIFE consists of two parts, the function body and the execution part.

//匿名函数的使用
//1. 声明一个变量,来接收一个匿名函数
var f = function () {

};

//事件驱动  window窗口对象的点击事件
var count = 0;
window.onclick = function () {
    console.log("第" + (++count) +"次点击了窗口...")
};

//IIFE自执行函数
;(function (a,b) {
    console.log(a + b);
})(10,20);

var result = (function (a,b) {
    return a + b;
})(10,20);
console.log("result:",result);

11. Closure function

What are closures?

A closure is a function that can access variables inside another function.

To understand closures, you need to understand the scope chain problem and the garbage collection mechanism problem (set to the life cycle of variables).

In JS, any function can be considered as a closure; the common situation is that global variables can be accessed in functions, and variables in ancestor elements can be accessed by nested functions.

function f(){
    var i = 1;
    function f2(){
        console.log(i);
    }
    return f2;
}

//f函数中的 变量i 是一个局部变量,局部变量只能在函数的内部被访问到
function f3(){
    console.log(i);
}

If you want to access variables inside a function outside of a function, what should you do?

Assume that we use the nested function as a bridge connecting the inside and outside, and when calling the outer function, return the inner function

function f() {
    var i = 1;
    return function () {
        return i++;
    }
}

console.log(f);
console.log(f());
console.log(f()());//1
console.log(f()());//1
//也就证明,每一次都是一个全新的环境,得到的值也是一样的  局部变量和函数在外部函数调用完毕后即销毁

//那么,利用对象之间的引用关系,可以保存当时执行的一个环境,进而将局部的变量保存下来
//垃圾回收机制中:对存在引用关系的对象 不会进行回收
var test = f();//此时test就是一个函数
console.log(test)
console.log(test());//1
console.log(test());//2
console.log(test());//3

var test2 = f();//此时又是一个新的闭包函数  当执行f()时,传递给test2的那个桥梁函数会记住当时所执行的上下文环境
console.log(test2);
console.log(test2());//1
console.log(test2());//2

Closure problem:

Closures should not be used too much, which may easily cause memory leaks;

However, the use of closures can avoid the pollution of global variables. In many advanced programs, there will be applications of closures. Later in the advanced class, closures will be used to privatize the properties and methods of objects.

Closures can currently be used to resolve:

​ In the loop, when there are asynchronous statements, the index cannot be obtained correctly.

// console.log(1111);
//回调函数:将一个函数作为另外一个函数的参数
//在JS中,有一个内置的延迟器,在指定时间后,去执行相应的操作
// setTimeout(function () {
//     console.log(2222);
// })
// console.log(3333);


//循环中,异步语句,获取索引的问题
// for (var i = 0; i < 10; i++) {
//     console.log("i:",i);
// }

for (var i = 0; i < 10; i++) {
    (function (j) {
        setTimeout(function () {
            console.log("内j:",j);
        })
    })(i);
}
console.log("外i:",i);

Guess you like

Origin blog.csdn.net/qq_39335404/article/details/131958137