Detailed JavaScript function declaration and recursive call _ basic knowledge

Source: Internet
Author: User
Tags anonymous function definition garbage collection

The way JavaScript functions are declared and invoked is a tiresome cliché, but there's something like that, you say it again and I say it again. Every time I see the JavaScript function written in the book or blog has four kinds of calling way, I will think of: anise word has four kinds of writing, you build it?

Although there are a bunch of bugs, JavaScript is fascinating. The core of the many beautiful features of JavaScript is the function of being a top-level object (first-class objects). Functions are created like other normal objects, assigned to variables, passed as parameters, as return values, and hold properties and methods. Functions, as top-level objects, give JavaScript powerful functional programming capabilities, as well as flexibility that is less easily controlled.

1. Function declaration

A variable declaration first creates an anonymous function and assigns it to a specified variable:

var f = function () {//function body}; 

Usually we don't have to care whether the scope of the expression on the right of the equal sign is global or a closure, because it can only be referenced by the variable F on the left side of the equal sign, and should focus on the scope of the variable F. If a reference to a function is corrupted (f = null) and the function is not assigned to any other variable or object property, the anonymous function is destroyed by the garbage collection mechanism because all references are lost.

You can also use function expressions to create functions:

 
 

Unlike a variable, this declarative method assigns a value to a built-in property name for a function. The function is also assigned to a variable with the same name as the current scope. (The function's Name property, configurable, enumerable, and writable are all false)

function f () {//function body} 
Console.log (f.name);//"F" 

JavaScript variables have one thing in particular, which is to advance the declaration of a variable, the function declaration of an expression, and the definition of the entire function, so you can use it before the function definition:

Console.log (F.name); "F" 
Console.log (f);//F () 
function f () {//function body} 

The declaration of a function expression is elevated to the top of the scope, and try the following code, which is not the focus of this article:

var a = 0; 
Console.log (a); 0 or a ()? 

Crockford recommends using the first way to declare a function forever, and he thinks the second way is to loosen the requirement that a function must be declared and used before it can cause confusion. (Crockford is a "conscientious programmer" like the "conscientious artist" in Russell's mouth, which is a metaphor for Wittgenstein's words).

function declaration

function f () {} 

Seems to be

var F = function f () {}; 

's Shorthand. and

 
 

expression that creates a function and assigns the built-in name property to "B". Then assign the function to variable a, you can use a () to invoke it externally, but you cannot use B (), because the function is assigned to a, so no longer automatically creates a variable B unless you use var B = A declares a variable B. Of course, the name of this function is "B" rather than "a".

You can also use function constructors to create functions:

var f = new Function ("A,b,c", "return a+b+c;"); 

This approach actually generates an anonymous function within the global scope and assigns it to the variable F.

2, Recursive call

Recursion is used to simplify many problems, which requires calling itself in a function body:

A simple factorial function 
var f = function (x) { 
  if (x = = 1) {return 
    1; 
  } else {return 
    x * F (x-1); 
  } 
}; 

The great flexibility of functions in JavaScript makes it difficult to use function names in recursion, and for the above variable declaration, F is a variable, so its value can easily be replaced:

var fn = f; 

The function is a value, it is assigned to FN, we expect to use FN (5) to calculate a value, but because the function is still referencing the variable F, so it does not work properly.

A functional declaration looks better, but it's a pity:

function f (x) { 
  if (x = = 1) {return 
    1; 
  } else {return 
    x * F (x-1);} 
} 
var fn = f; 
f = function () {}; May been warning by browser 

It seems that once we have defined a recursive function, we should be careful not to change the name of the variable easily.

It's all about functional invocation, and there are other ways in which functions are called, such as Object methods.

We often declare objects like this:

var obj1 = { 
  Num:5, 
  fac:function (x) { 
    /function body 
  } 

Declares an anonymous function and assigns it to the object's properties (FAC).

If we want to write a recursive here, we need to refer to the property itself:

var obj1 = { 
  Num:5, 
  fac:function (x) { 
    if (x = = 1) {return 
      1; 
    } else {return 
      x * obj1 . FAC (X-1); 
    } 
  } 
; 

Of course, it also encounters the same problem as the function invocation method:

var obj2 = {FAC:OBJ1.FAC}; 
Obj1 = {}; 
OBJ2.FAC (5); Sadness 

Method is assigned to the FAC property of the Obj2, the interior still refers to the OBJ1.FAC, so ... Has failed.

A different approach would improve:

var obj1 = { 
   Num:5, 
   fac:function (x) { 
    if (x = = 1) {return 
      1; 
    } else {return 
      x * THIS.FAC ( x-1); 
    } 
  } 
; 
var obj2 = {FAC:OBJ1.FAC}; 
Obj1 = {}; 

The This keyword gets the properties in the context of the function execution, so that when the OBJ2.FAC is executed, the Obj2 FAC property is referenced inside the function.

But functions can also be arbitrarily modified context to invoke, that is omnipotent call and apply:

Obj3 = {}; 

Then the recursive function does not work properly.

We should try to solve this problem, remember the way of a function declaration mentioned earlier?

 
 

This type of declaration is called an inline function, although no variable B is declared outside the function, but within the function, B () can be used to invoke its own, so the inline

var fn = function f (x) { 
  //try If you write ' var f = 0; ' Here 
  if (x = = 1) {return 
    1; 
  } else { 
    retur n x * f (x-1); 
  } 
}; 
var fn2 = fn; 
fn = null; 
 Here's the difference between "var F = function f () {}" and "function f () {}" 
var f = function f (x) { 
  if ( x = = 1) {return 
    1; 
  } else {return 
    x * F (x-1);} 
}; 
var fn2 = f; 
f = null; 
var obj1 = { 
  num:5, 
  fac:function f (x) { 
    if (x = = 1) {return 
      1; 
    } else {return 
      x * F (x -1);}} 
; 
var obj2 = {FAC:OBJ1.FAC}; 
Obj1 = {}; 
OBJ2.FAC (5); Ok 
 
var obj3 = {}; 
Obj1.fac.call (OBJ3, 5); Ok 

In this way, we have a name that can be used internally, without worrying about who the recursive function is assigned to and how it is invoked.

The arguments object inside the JavaScript function has a callee attribute that points to the function itself. Therefore, you can also use Arguments.callee to invoke functions internally:

function f (x) { 
  if (x = = 1) {return 
    1; 
  } else {return 
    x * Arguments.callee (x-1);} 
} 

However, Arguments.callee is a property that is ready to be deprecated and is likely to disappear in future ECMAScript versions, and Arguments.callee cannot be used when "use strict" in ECMAScript 5.

The last suggestion is: If you want to declare a recursive function, use the new function in this way, the function created by the functions constructor compiles a function every time it is invoked, and a recursive call raises a performance problem-you will find that your memory is quickly depleted.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Related Article

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.