First-class citizens in the Javascript world-Functions

Source: Internet
Author: User
Tags tagname
In many traditional languages (such as C/C ++/Java/C #), functions exist as second-class citizens, you can only declare a function with the keyword of the language and call it. If you need to pass the function as a parameter to another function, or assign a value to a local variable, or return a value, you need to use function pointers and delegate to perform a discount. In the Javascript world, a function is a first-class citizen. It not only has the usage (declaration and call) of all traditional functions, but also can assign values, PASS Parameters, and return values like simple values, such a function is also called First-class function). In addition, functions in Javascript also act as class constructor and are also an instance of the function class ). Such multiple identities make JavaScript Functions very important. 1. Entry-level JavaScript Functions of JavaScript Functions follow the principle of first sound and then use as common languages. function names can only contain Letters, numbers, underscores, or $And cannot start with a number. There are two common methods to declare functions:
// Directly declare the function myfuncfunction myfunc (/* arguments */) {} // assign the anonymous function to the local variable myfuncvar myfunc = function (/* arguments */){}

Note that there are minor differences between the above two function declaration methods: the first method isNamed Functions, Whether it is declared inBefore calling,After the call, Or evenNot executed(For example, after the return statement or never in the true Branch), all are accessible throughout the scope. The second method is to assign an anonymous function to a variable, strictly speaking, this is not a function declaration but a function expression. Before assigning values, this function cannot be accessed by any code.The assignment must be completed before the call.Otherwise, an error occurs: "typeerror:
Undefined is not a function ". For example:

Myfunc1 (); // can be called normally, because myfunc1 uses the directly declared function myfunc1 () {} myfunc2 (); // error typeerror: undefined is not a functionvar myfunc2 = function (){};
The basic call method of a function is the same as that of a traditional language. Use a pair of brackets to call the function: myfunc (). JavaScript Functions also support direct or indirect recursive calls. For example, the typical Fibonacci function can be implemented using JavaScript as follows:
function fib(n) {  if (n == 1 || n == 2) {    return 1;  } else {    return fib(n - 2) + fib(n - 1);  }}
A JavaScript function can handle variable-length parameters. Each function has a local variable named arguments, which is an array-liked object, it contains all the parameters passed in during the call. The Length attribute indicates the number of parameters. For example:
function test() {  alert(arguments.length);}test(1); // 1test(1, 'a'); // 2test(true, [], {}); // 3

Arguments can be used to implement functions similar to C-language printf, or to implement method polymorphism.

Ii. Advanced JavaScript Functions2.1 anonymous and nested Functions
In JavaScript, you can declare a function without a name, called an anonymous function ). At the same time, JavaScript allows you to declare a function inside a function, called a nested function. The scope of a nested function is the entire parent function. In the previous part of the function declaration, we can see a usage of anonymous and nested functions. Since anonymous functions do not have names, new variables will not be introduced to pollute the context, in addition, new variable scopes are introduced. Therefore, anonymous functions are often used to prevent global environment pollution.
The javascript runtime has a special global object, which stores global functions and variables. In actual development, several third-party libraries or multiple JS files are often used, if repeated variables or function declarations are accidentally introduced to the global object, the code execution will be chaotic. For example, if two JS files are successively introduced and their own function log is defined as internal use, then the second introduced function willOverwriteThe first definition andNo error is thrown.In subsequent execution, calling the log function may cause errors. At this time, using an anonymous function to wrap the logic of the entire JS can avoid this error. This method has been used by the vast majority of Open Source JS libraries.
(Function () {// anonymous function log (MSG) {console. Log (MSG) ;}// other code} (); // execute immediately

The above code is a simple example. The scope of the log function is limited to this anonymous function, while the anonymous function is included by a pair of parentheses () to form a function expression, the expression value is a function, followed by a pair of parentheses, indicating that the function is executed immediately, so that the original code can be executed normally once. However, the declared functions and variables declared through VaR are internal and cannot be accessed by any code other than anonymous functions. If you need to expose some functions as interfaces, you can use the following methods:

VaR mylib = (function (global) {function log (MSG) {console. log (MSG);} log1 = log; // Method 1: use the default behavior declared by variables without VaR to make log1 a global variable (not recommended. 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 set 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 high-order function. All functions in javascript can be used as high-order functions. This is also a feature of the first type of function. Next we will analyze the two usage methods respectively.
Function negative (n) {return-N; // obtain the opposite value of n} Function Square (n) {return N * n; // The square of n} function process (Nums, callback) {var result = []; for (VAR I = 0, length = nums. length; I <length; I ++) {result [I] = callback (Nums [I]); // transmits all elements in the array Nums to callback for processing, 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 code above shows an example of passing a function as a parameter to another function's process call. In the implementation of the Process function, callback is treated as a black box. It is responsible for passing the parameter to it and then obtaining the return value, the specific implementation of callback is unclear before the call. Only when 20 rows and 22 rows are executed, callback is represented by negative or square, respectively, and the opposite value or square value is taken for each element.
Function Generator () {var I = 0; return function () {return I ++ ;};} var gen1 = generator (); // obtain a natural number generator var gen2 = generator (); // obtain another natural number generator var R1 = gen1 (); // R1 = 0var r2 = gen1 (); // r2 = 1var R3 = gen2 (); // R3 = 0var r4 = gen2 (); // r4 = 1
The code above shows an example of using a function as the return value. Generator is a natural number generator function, and the return value is a natural number generator function. Each time you call generator, an anonymous function is returned as a result. This anonymous function returns each natural number in sequence when called. Variable I in generator increases by 1 every time this anonymous function is called, which is actually a closure. Next we will introduce the closure.2.3 closure (closure)Closure is not a new concept. Closure is used in many functional languages. In JavaScript, a closure is used when you use variables in the scope of external functions in Embedded functions. A common analogy is used to explain the relationship between a closure and a class: A class is a data with a function, and a closure is a function with data. The variables used in the closure have a feature that they are not released when the parent function returns, but end with the closure lifecycle. For example, in the example of generator in the previous section, gen1 and gen2 use independent variables I (gen2 I is not affected when gen1 I auto-increment 1, and vice versa), as long as gen1 or gen2 variables are not garbage collected by the JavaScript engine, their respective variable I will not be released. In JavaScript programming, the closure will be used without knowing it. This feature of the closure is easy to use, but also easily leads to problems similar to memory leakage. For example:
var elem = document.getElementById('test');elem.addEventListener('click', function() {  alert('You clicked ' + elem.tagName);});

The purpose of this Code is to display its label name when you click a knot. It registers an anonymous function as a click event handler for a DOM node. The function references a DOM object ELEM, the closure is formed. 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 exists as the event handler function of the DOM object, so the closure will not be released before the DOM object is released, even if the DOM object is deleted in the DOM tree, because of this circular reference, neither the DOM object nor the closure will be released. The following method can be used to avoid Memory leakage:

VaR ELEM = document. getelementbyid ('test'); ELEM. addeventlistener ('click', function () {alert ('You clicked' + this. tagname); // no longer directly referencing ELEM variable });
The above Code uses this to replace ELEM (in the DOM Event Handler function, this pointer points to the DOM element itself), so that JS runtime does not consider this function to use the parent class variable, therefore, no closure is formed.

The closure will also cause many similar memory leaks. You only need to pay attention to the closure when writing code to avoid such problems as much as possible.2.4 class ConstructorJavaScript Functions serve as class constructor at the same time. Therefore, you can use the new keyword to create class instances as long as you declare a function.

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 class constructor. In this case, this points to the newly created instance object and adds attributes and methods to the instance, for details about object-oriented JavaScript programming, refer to this article. Here I want to talk about the return value of JavaScript Functions when they are used as class constructors.

Function myclass (name) {This. Name = Name; return name; // the return value of the constructor ?} VaR obj1 = new myclass ('foo'); var obj2 = myclass ('foo'); var obj3 = new myclass ({}); var obj4 = myclass ({});
The above constructor is special. If there is a return statement, then obj1 ~ What objects does obj4 point? The actual result is as follows:
  • Obj1 = myclass object
  • Obj2 = 'foo'
  • Obj3 = {}
  • Obj4 = {}
The specific reason is explained in this article. This article will not go into details. because constructors with return values will produce strange results, do not call return statements with return values in Constructors (null return is acceptable ). Iii. JavaScript function monstersWelcome to the monster-level function teaching area. Here we will show you how to calmly face the old monsters...
3.1 function classDuring JavaScript running, a built-in class is called function. Declaring a function with the function keyword is actually a shorthand form for creating a function class object, all functions have all functions, such as call, apply, and bind. You can use the instanceof keyword to verify this statement. Since a function is a class, its constructor is a function (it is also an object of the function class). It should be able to generate a function object through the new keyword. The first monster came, that is, how to use the function class to construct a function. Function Syntax:
new Function ([arg1[, arg2[, ... argN]],] functionBody)
Here, arg1, arg2 ,... argn is a string that represents the parameter name, And functionbody is also a string that represents the function body. The preceding parameter name can be multiple or fewer. The function constructor regards the last parameter as the function body, the preceding parameters are processed as parameters.
var func1 = new Function('name', 'return "Hello, " + name + "!";');func1('Ghostheaven'); // Hello, Ghostheaven!
The above method constructs a function through function, which is exactly the same as other functions declared with the function keyword. Many people may ask why such a monster is needed? "What exists is reasonable." The function class has its unique purpose. You can use it to dynamically generate various function logics or replace the functions of eval functions, in addition, the current environment will not be contaminated *.3.2 self-update function)In many languages, once declared, a function with the same name cannot be declared again. Otherwise, a syntax error occurs. Functions in javascript can not only be declared repeatedly, but can also be updated by themselves. Eat your monsters by yourself!
function selfUpdate() {  window.selfUpdate = function() {    alert('second run!');  };  alert('first run!');}selfUpdate(); // first run!selfUpdate(); // second run!

This type of function can be used to run the logic only once. After the first operation, it is replaced with a new logic.

SummaryJavaScript Functions are very powerful, and they also bring many negative problems while effectively solving many problems. The use of monster-level functions is generally a little-known method. Unless necessary, it may cause difficulty in reading code and affect the development efficiency of the team.
* The strict mode is introduced in the new ecmascript. In the strict mode, Eval functions are greatly restricted and the environment is not polluted.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.