JavaScript supports recursive invocation of functions.
The so-called recursive function is to call the function itself in the function body.
A common example of using recursive functions is to find factorial.
Use recursive function to ask 6!.
The code is as follows |
Copy Code |
<script type= "Text/javascript" > function fact (num) { if (num<=1) { return 1; }else{ Return Num*fact (num-1); } } document.write (Fact (6)); </script> |
But this may appear in JS error:
The code is as follows |
Copy Code |
var anotherfactorial = factorial; Factorial=null; Alert (Anoterfactorial (4)); |
Because the internal factorial no longer exists when the anoterfactorial is invoked.
The solution is to be solved by Arguments.callee.
As follows:
The code is as follows |
Copy Code |
function factorial (num) { if (num <= 1) { return 1; } Else { Return Num*arguments.callee (num-1); } var anotherfactorial = factorial; factorial = null; Alert (Anotherfactorial (4)); } |
If in a very complex program we may only need to call the function once, for the sake of the simplification of the function we should certainly strive for less function name definition, it is very natural to think of using anonymous function to execute directly. But what if the anonymous function implements recursion? Arguments.callee just came in handy, and he was referring to a reference to the currently executing function.
Arguments.callee
In the JavaScript function body, the identifier arguments has a special meaning. It is a special property of the calling object that refers to the arguments object. The Arugments object is like an array, notice that it's just like not ha. JavaScript function body, arguments like an array (not a real array, is a arguments object, again), has the length property, can represent the number of parameters passed to the function.
Referencing a formal parameter can be either a parameter name or a arguments[] array, where Arguments[0] represents the first argument. So, the arguments object in JavaScript is the actual parameter of the function, and below, let's go into this magical kingdom and get a glimpse of it.
Arguments.length properties: JS does not take the initiative for you to determine how many parameters you have passed to the function, if you pass more, the superfluous part is not used, if you are less, then the parameter value is not transmitted undefined
So we can use the arguments length property to detect if the correct number of actual arguments are used when calling a function, because JavaScript doesn't do it for you.
The code is as follows |
Copy Code |
function f (x,y,z) { First check that the number of parameters passed is correct if (arguments.length!= 3) { throw new Error ("function f called with" + Arguments.length + "arguments, but it is not 3 arguments."); } Run the real function below } |
Arguments also provides us with the possibility of is to pass any number of actual arguments to a function: for example, I want to judge the size of some numbers you pass to me, take out the biggest one, right, yes, how many parameters you pass, but only if you're going to pass numbers, because I'm too lazy to judge within the function.
The code is as follows |
Copy Code |
function Max () { var m = number.negative_infinity;//number.negative_infinity The smallest number in JavaScript for (var i = 0; i < arguments.length; i++) { As long as any one argument is larger than M, then m becomes the value of this parameter. if (Arguments[i] > m) m = Arguments[i]; } return m; } |
What do you think? This is a clever method, isn't it?
Explain that the arguments is consistent with the actual form parameters: for example, you pass a function called param parameter, and only this one parameter, then param and arguments[0] are references to this parameter value, change one of the values, that is, change the value of both.
The code is as follows |
Copy Code |
function Change (param) { For example, I preach the param for Simaopig, then alert is Simaopig, If you don't preach anything, alert undefined. alert (param); Change the value of this parameter with Arguments[0] Arguments[0] = ' Xiaoxiaozi '; Yes, the value becomes Xiaoxiaozi. alert (param); }
|
Arguments Callee Property: The callee property of the arguments is used to refer to the currently executing function, which is very beneficial to the unnamed function call itself.
Now use the arguments of this callee simple implementation.
The code is as follows |
Copy Code |
Using the direct quantity of function, using Arguments.callee attribute to realize recursive function var result = function (x) { if (x<=1) return 1; Return X*arguments.callee (x-1); }; |
JS recursive function calls itself when the insurance method.
From JS Advanced Program Design
A typical factorial recursive function:
The code is as follows |
Copy Code |
function fact (num) { if (num<=1) { return 1; }else{ Return Num*fact (num-1); } } |
The following code can cause an error:
The code is as follows |
Copy Code |
var anotherfact = fact; fact = null; Alert (Antherfact (4)); Error |
Since fact is no longer a function, an error occurs.
Use Arguments.callee to resolve the problem, which is a pointer to the function being executed.
The new function is:
The code is as follows |
Copy Code |
function fact (num) { if (num<=1) { return 1; }else{ Return Num*arguments.callee (num-1); Changes are made here. } } var anotherfact = fact; fact = null; Alert (Antherfact (4)); The result is 24. |
The improvement of JS common recursion
A recursive function is composed of a function that invokes itself by name, as follows:
The code is as follows |
Copy Code |
function factorial (num) { if (num<=1) { return 1; } Else { return num * factorial (num-1); } } |
This is a classic factorial function. There seems to be nothing wrong with the surface, but the following code can cause it to go wrong.
The code is as follows |
Copy Code |
var anotherfactorial = factorial; Anotherfactorial (4); Output 24 factorial = null; Anotherfactorial (4); Typeerror:property ' factorial ' of Object [object Window] is not a function chrome |
The test
The reason is that the name of the function we defined is actually a pointer to a function, which defines the anotherfactorial and points to that function, so calling anotherfactorial (4) can successfully output 24
At this time factorial = null; Then the reference to the execution definition function is left anotherfactorial, then the error information is displayed in the call to Anotherfactorial (4).
You can use Arguments.callee to override the factorial in the function definition.
The definition of a function becomes:
The code is as follows |
Copy Code |
function factorial (num) { if (num<=1) { return 1; } Else { Return num * Arguments.callee (NUM-1); } } |
Then in the 4 lines above the test code, the last line of test code can also successfully output 24.