Home  >  Article  >  Web Front-end  >  Detailed explanation of JavaScript functions_Basic knowledge

Detailed explanation of JavaScript functions_Basic knowledge

WBOY
WBOYOriginal
2016-05-16 16:31:141230browse

Introduction

In many traditional languages ​​(C/C/Java/C#, etc.), functions exist as second-class citizens. You can only declare a function using language keywords and then call it. If you need to use the function as a parameter To pass it to another function, assign it to a local variable, or use it as a return value, you need to go through special methods such as function pointer and delegate.
In the JavaScript world, functions are first-class citizens. They not only have all the ways of using traditional functions (declaration and calling), but can also assign values, pass parameters, and return like simple values. Such functions are also called third-class functions. First-class Function. Not only that, the function in JavaScript also acts as the constructor of the class and is an instance of the Function class. Such multiple identities make JavaScript functions very important.

1. Entry-level JavaScript functions

Like other languages, JavaScript functions follow the principle of declaration first and use later. Function names can only contain letters, numbers, underscores or $, and cannot start with numbers. There are two common ways to declare functions:

Copy code The code is as follows:

// Directly declare the function myfunc
function myfunc(/* arguments */) {
}

//Assign the anonymous function to the local variable myfunc
var myfunc = function(/* arguments */) {
}

Note that there are subtle differences between the above two methods of function declaration: the first method is a named function when declared, whether it is declared before the call, after the call, or even in a position that will not be executed (such as return statement or in a branch that will never be true), are accessible in the entire scope; the second way is by assigning an anonymous function to a variable, which is not strictly a function declaration (function declaration ) is a function expression. This function cannot be accessed by any code before assignment, which means that the assignment must be completed before calling, otherwise an error will occur when calling: "TypeError: undefined is not a function ". For example:

Copy code The code is as follows:

myfunc1(); // Can be called normally because myfunc1 is declared directly

function myfunc1() {
}

myfunc2(); // Error TypeError: undefined is not a function

var myfunc2 = function() {
};


The basic method of calling a function is the same as in traditional languages ​​using a pair of parentheses: myfunc(). JavaScript functions also support direct or indirect recursive calls. For example, the classic Fibonacci function can be implemented in JavaScript like this:

Copy code The code is as follows:

function fib(n) {
If (n == 1 || n == 2) {
Return 1;
} else {
Return fib(n - 2) fib(n - 1);
}
}

Functions in JavaScript can handle variable-length parameters. Inside the function, there is a local variable named arguments, which is an array-like object that contains all the parameters passed in when called. The length attribute indicates the number of parameters. For example:

Copy code The code is as follows:

function test() {
alert(arguments.length);
}

test(1); // 1
test(1, 'a'); // 2
test(true, [], {}); // 3 Arguments can be used to implement functions similar to C language printf, and can also be used to implement method polymorphism.

2. Advanced JavaScript functions

2.1 Anonymous functions and nested functions

In JavaScript, you can declare a function without a name, called an anonymous function. At the same time, JavaScript also allows functions to be declared inside functions, called nested functions. The scope of a nested function is the entire parent function.

In the previous function declaration section, we saw a use of anonymous functions and nested functions. Since anonymous functions have no names, they will not introduce new variables to pollute the context, and will bring new variable scopes. Therefore, anonymous functions are often is used to prevent global environmental pollution.

There is a special global environment (global object) in the JavaScript runtime. This object stores global functions and variables. In actual development, several third-party libraries or multiple js files are often used. If you accidentally introduce duplication in the global object Variable or function declaration will cause confusion in code execution. For example, two js files are introduced one after another, and each defines its own function log for internal use. The second introduced function will overwrite the first definition and will not throw any errors. Calling the log function in subsequent executions may cause problems. causing errors. At this time, using an anonymous function to wrap the logic in the entire js can avoid this error. This method has been used by most open source js libraries.

Copy code The code is as follows:

(function() { // Anonymous function

function log(msg) {
console.log(msg);
}

// Other codes

}()); // Execute immediately

The above code is a simple example. The scope of the log function is limited to this anonymous function, and the anonymous function is surrounded by a pair of parentheses () outside to form a function expression. The expression The value is a function, followed by a pair of parentheses to indicate that the function will be executed immediately, allowing the original code to be executed normally. However, functions declared in this way, variables declared via var, etc. are internal and cannot be accessed by any code other than anonymous functions. If you need to expose some functions as interfaces, there are several methods:

Copy code The code is as follows:

var mylib = (function(global) {

function log(msg) {
console.log(msg);
}

log1 = log; // Method 1: Use the default behavior of variable declaration without var and make log1 a global variable (not recommended)

global.log2 = log; // Method 2: Add the log2 attribute directly to the global object and assign the value to the log function (recommended)

return { // Method 3: Obtain a series of interface function collection objects through the return value of the anonymous function, and assign them to the global variable mylib (recommended)
Log: log
};

}(window));

2.2 High-order Function

If a function is used as a parameter or return value, it is called a higher-order function. All functions in JavaScript can be used as higher-order functions. This is also a characteristic of the first type of function. Below we will analyze these two usage methods respectively.

Copy code The code is as follows:

function negative(n) {
Return -n; // Take the opposite value of n
}

function square(n) {
Return n*n; // n squared
}

function process(nums, callback) {
var result = [];

for(var i = 0, length = nums.length; i < length; i ) {
result[i] = callback(nums[i]); // Pass all elements in the array nums to callback for processing, and save the return value as the result
}

Return result;
}

var nums = [-3, -2, -1, 0, 1, 2, 3, 4];
var n_neg = process(nums, negative);
// n_neg = [3, 2, 1, 0, -1, -2, -3, -4];
var n_square = process(nums, square);
// n_square = [9, 4, 1, 0, 1, 4, 9, 16];

The above code shows an example of passing a function as a parameter into another function process call. In the implementation of the process function, the callback is treated as a black box, responsible for passing the parameters to it, and then getting the return value. The specific implementation of callback was not clear before. Only when lines 20 and 22 are executed, the callback is represented by negative or square respectively, and the opposite or square value operation is performed on each element respectively.

Copy code The code is as follows:

function generator() {
var i = 0;
Return function() {
Return i ;
};
}

var gen1 = generator(); // Get a natural number generator
var gen2 = generator(); // Get another natural number generator
var r1 = gen1(); // r1 = 0
var r2 = gen1(); // r2 = 1
var r3 = gen2(); // r3 = 0
var r4 = gen2(); // r4 = 1

The above code shows an example of using a function as a return value. generator is a natural number generator function, and the return value is a natural number generator function. Each time the generator is called, an anonymous function is returned as the result. This anonymous function returns each natural number in turn when it is actually called. The variable i in the generator will increase by 1 every time this anonymous function is called. This is actually a closure. Let’s introduce closures below.


2.3 Closure
Closure (Closure) is not a new concept. Closures are used in many functional languages. In JavaScript, closures are used when you use variables within the scope of an external function within an inline function. Use a common analogy to explain the relationship between closures and classes: classes are data with functions, and closures are functions with data.
One characteristic of variables used in closures is that they are not released when the parent function returns, but end when the closure life cycle ends. For example, like the generator example in the previous section, gen1 and gen2 use independent variables i (when i of gen1 increases by 1, i of gen2 is not affected, and vice versa), as long as gen1 or gen2 If the two variables are not garbage collected by the JavaScript engine, their respective variable i will not be released. In JavaScript programming, closures are used unconsciously. While this feature of closures brings ease of use, it can also easily cause problems like memory leaks. For example:

Copy code The code is as follows:

var elem = document.getElementById('test');
elem.addEventListener('click', function() {
alert('You clicked ' elem.tagName);
});

The function of this code is to display the label name of a node when it is clicked. It registers an anonymous function as a click event processing function of a DOM node. A DOM object elem is referenced in the function, forming a closed Bag. This will generate a circular reference, namely: DOM-> Closure->DOM-> Closure... The DOM object will not be released before the closure is released; and the closure serves as the event handling function of the DOM object exists, so the closure will not be released before the DOM object is released. Even if the DOM object is deleted in the DOM tree, due to the existence of this circular reference, neither the DOM object nor the closure will be released. You can avoid this memory leak by using the following method:

Copy code The code is as follows:

var elem = document.getElementById('test');
elem.addEventListener('click', function() {
alert('You clicked ' this.tagName); // No longer refer to the elem variable directly
});

In the above code, this is used instead of elem (in the DOM event handling function, the this pointer points to the DOM element itself), so that the JS runtime no longer thinks that the variable of the parent class is used in this function, so a closure is no longer formed. .
Closures will also bring about many similar memory leak problems. Only pay attention to closures when writing code to try to avoid such problems.

2.4 Class Constructor
JavaScript functions also serve as constructors of classes, so as long as you declare a function, you can use the new keyword to create an instance of the class.

Copy code The code is as follows:

function Person(name) {
This.name = name;
This.toString = function() {
Return 'Hello, ' this.name '!';
};
}

var p = new Person('Ghostheaven');
alert(p); // Hello, Ghostheaven! In the above example, the Person function is used as the constructor of the class. At this time, this points to the newly created instance object. You can add properties and methods to the instance. Regarding detailed object-oriented JavaScript programming You can refer to this article. What I want to talk about here is the return value issue when JavaScript functions are used as class constructors.

Copy code The code is as follows:

function MyClass(name) {
This.name = name;
Return name; // Return value of constructor?
}

var obj1 = new MyClass('foo');
var obj2 = MyClass('foo');
var obj3 = new MyClass({});
var obj4 = MyClass({});

The above constructor is quite special, it has a return statement, so what objects do obj1~obj4 point to respectively? The actual result is this:

Copy code The code is as follows:

obj1 = MyClass object
obj2 = 'foo'
obj3 = {}
obj4 = {}

The specific reason is explained in this article, and I will not go into details in this article. Since the constructor with a return value will produce strange results, do not call a return statement with a return value in the constructor (an empty return is fine).

3. JavaScript function monster level

Welcome to the monster-level function teaching area, where we will teach you how to face monsters calmly and comfortably. . .

3.1 Function class
There is a built-in class called Function in the JavaScript runtime. Declaring a function with the function keyword is actually a shorthand form of creating a Function class object. All functions have all the methods of the Function class, such as call, apply, and bind. Wait, you can verify this statement through the instanceof keyword.
Since Function is a class, its constructor is Function (itself is also an object of the Function class), and it should be possible to generate a function object through the new keyword. Here comes the first monster, which is how to construct a function using the Function class. The syntax of Function is as follows:

Copy code The code is as follows:

new Function ([arg1[, arg2[, ... argN]],] functionBody)

Among them, arg1, arg2, ... argN are strings, representing parameter names, and functionBody is also a string, representing the function body. The previous parameter names can be more or less. The constructor of Function will treat the last parameter as In the function body, the previous ones are treated as parameters.

Copy code The code is as follows:

var func1 = new Function('name', 'return "Hello, " name "!";');
func1('Ghostheaven'); // Hello, Ghostheaven!

The above method constructs a function through Function. This function is exactly the same as other functions declared with the function keyword.
Seeing this, many people may ask why such a monster is needed? "Whatever exists is reasonable." The Function class has its unique use. You can use it to dynamically generate various function logic, or replace the function of the eval function, and keep the current environment from being polluted*.


3.2 Self-update Function
In many languages, once a function is declared, it cannot declare a function with the same name again, otherwise a syntax error will occur. However, functions in JavaScript can not only be declared repeatedly, but also update themselves. The monster that eats itself is here!

Copy code The code is as follows:

function selfUpdate() {
window.selfUpdate = function() {
alert('second run!');
};

alert('first run!');
}

selfUpdate(); // first run!
selfUpdate(); // second run! This function can be used to run logic only once, and replace the entire logic with a new piece of logic after the first run.

Summary

JavaScript functions are very powerful. While they solve many problems beautifully, they also bring about many negative problems. The usage of monster-level functions is usually some little-known usage. Do not use it lightly unless it is particularly necessary. Otherwise, it will make it difficult to read the code and affect the team's development efficiency.

* Strict mode is introduced in the new ECMAScript. In strict mode, the eval function is greatly restricted, and it can also ensure that the environment is not polluted

Have you understood it, friends? It is very practical. If there is anything missing, please ask the experts for guidance and we can make progress together

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:Summary of PHP PDO operations_javascript skillsNext article:Summary of PHP PDO operations_javascript skills

Related articles

See more