function

Functions are first-class citizens in the JavaScript world

function

Why put the function (function) at the very beginning of the "core concepts" in this section? Because functions are the first-class citizens in the JavaScript world, the so-called first-class citizens refer to functions that are equal to other data types and can be assigned to other variables or passed into another function as parameters, Or as the return value of another function. There are functions everywhere in this world

1.1 Four common forms of functions: Almost all JavaScript codes we write are inseparable from functions, either in the form of declarations, expressions, nesting, or closures . See the code example below.

 //Function declaration form
function func(){
    console.log("Function declaration form")
}

//One of the expression forms of the function
let func0 =function(){
    console.log("One of the expression forms of the function");
}

//Function expression form 2
(function func1() {})

//Nested form of functions
let func2 = function(){
    console.log("Nested form of functions");
    let func3 = function(){
        console.log("func2 is nested in func1")
    }
    func3();
}

// Function closure pattern
let func4 = function(){
    var a = "func4"; 
    return function(){
        console.log("I am a function in the form of a closure:"+a);
    }
}
//All functions are called through a pair of brackets "()"
func();
func0();
func1();
func2();
func4()();

1.2 Function declaration promotion Only the functions that declare the shape have the characteristics of promotion. What is "enhancement"? The so-called promotion means that the execution order of the code is promoted to the top.

console.log(func0); //>> func0() {return 0}
console.log(func1); //>> undefined
//The declaration form of the function
function func0() {
return 0;
}
//The expression form of the function
var func1 = function() {
return 1;
};

1.3 IIFE and anonymous functions, well-known functions There is also a function call method in the form of IIFE (Immediately-Invoked Function Expression), which is very suitable for anonymous function calls. The feature is that there is a bracket "(" on the left side of the keyword function, and a closing bracket ") on the right side. "There are two ways to place it, one is to the left of the pair of calling brackets, and the other is to the right of the pair of calling brackets. In the following code example, these two writing methods are equivalent and both are ok.

(function(){
console.log("I am an anonymous function that runs immediately");
})();
(function(){
console.log("I am also an anonymous function that runs immediately");
}());

Since anonymous functions plus IIFE make the code so concise, why do we need to name the function-a famous function? First of all, one of the best reasons is of course to facilitate recursion. Recursion requires a function to call itself. If a function does not have a name, it cannot effectively find the function itself through an identifier (name) for calling. The name of the function can be read through the name attribute

//The function call itself is called recursion, and the function name is "func"
(function func(i){
console.log("The function name is "+func.name+", the first "+i+" call")
if(i<3){//recursive exit
func(++i);//recursive
}
})(1);
//>> The function is called func, the first call
//>> The function is called func, the second call
//>> The function is called func, the third call

Secondly, anonymous functions are not conducive to debugging stack traces. Well-known functions can quickly locate code positions during debugging based on their names. Finally, anonymous functions seem a bit unintuitive. Of course, it will be quite intuitive to use after familiarity, this book will use IIFE extensively.

1.4 Is there really no way for an anonymous function to call itself recursively? Have! Each function has an arguments property, which represents a collection of function parameters, and the collection has a method called callee, which represents the function itself, so that it can call itself through arguments.callee(). //The function call itself is called recursion, and the function name is "func"

(function (i){
console.log("The function name is "+func.name+", the first "+i+" call")
if(i<3){//recursive exit
arguments.callee(++i);
}
})(1);
//>> The function is called func, the first call
//>> The function is called func, the second call
//>> The function is called func, the third call

1.5 Define scope Before ES6, JavaScript had no block-level scope, only function scope. That is to say, functions are more like the curly bracket pair "{ }" in java language, which can define the visible area of ​​the variable-the scope. After the emergence of ES6, JavaScript has block-level scope, which is implemented through the let keyword.

1.6 Arrow functions Declaring a function with (parameter) => {expression} is called an arrow function (also called a lamda expression). Arrow function is one of the syntactic sugar that ES6 brings to us. The main intention is to define a lightweight inline callback function. Of course, the most intuitive benefit is that you can type a few characters less. In the following code, using the function keyword to declare an anonymous function is equivalent to using the arrow => to declare the function.

(function(i){
console.log(i);
})(1);
((i)=>{
console.log(i);
})(1);

The arrow function does not expose the arguments object, so if you access the arguments, it will be accessed as a normal variable

((a)=>{
    console.log(a);//>> 1

    console.log(arguments.length);//>> Uncaught ReferenceError: arguments is not defined
})(1);

An obvious function of the arrow function is to keep the pointing of this, always pointing to the context in which it was defined. Finally, arrow functions do not have their own super or new.target. This sentence may not be easy to understand, you can refer to the following code:

var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor

That is to say, the arrow function cannot be used as a constructor, so it cannot be operated by new, and there is no new.target.

1.7 Higher-order functions If a function can receive another function as a parameter, the function is called a higher-order function. Function as a parameter? This seems too strange. In fact, because in JavaScript, a function can be assigned to a variable, and a variable can be passed to a function as a parameter, so a function can also be passed to a function as a parameter. One of the most common forms of higher-order functions is the callback function.

function fn1(callback){
if(callback){
callback();
}
}
fn1(function(){
console.log("Higher Order Function");//>> Higher Order Function
});