How do JavaScript closures implement overloading of functions?

Source: Internet
Author: User

This article and we share the main is the refinement of JavaScript closure to implement function overloading related content, come to see it, I hope to everyoneLearn JavaScripthelpful.
1. Preparation of Knowledge
1.1 Closures
a closure is a scope that a function creates when it is created, allowing the function to access and manipulate variables other than the self function. Closures allow a function to access all variables and functions that exist within the scope of the function declaration.
<script>
var outervalue = "Ninja";
var later;
function Outerfunction () {
var innervalue = ' samural ';
function Innerfunction (paramvalue) {
Console.log (Outervalue);//Ninja
Console.log (Innervalue);//Samural
Console.log (paramvalue);//Wakizshai
Console.log (toolate); Ronin
            }
later = innerfunction;
        }
outerfunction ();
var toolate = "Ronin";
later (' Wakizshai ');
</script>
The Innerfunction method has access to variables and functions within the scope of the declaration before the method call. When the function declaration is innerfunction, a closure is created at the same time. Declare the function at this moment all variables (parameters) in the scope and outside the scope of the function are saved in the closure.
1.2 Function Context
The context of a function is the this of the function, and the function is called in a different way than the context of the function . The following four ways are roughly included
1.2.1 As a function call
//define a function ninja () {};
//Call to function, Ninja this is window
Ninja ();
by declaring a function and using () The function call, this is the Window object. In other words, this function is global.
1.2.2 As a method call
var o = {};
//o The whatever method of the object as an anonymous function
o.whatever= function () {};
//As a method to invoke, whatever this is the O object O.whatever ();
call the function as a method of the object, then this object is the context of the method (this is the object that this refers to)
1.2.3 called as a constructor
function Ninja () {
this.skulk = function () {
//Verify judgment by returning this
return this;
}
}
//Through the new keyword, make Ninja () the constructor to call var ninja1 = new Ninja (); var ninja2 = new Ninja ();
//Ninja1.skulk () returns the NINJA1 description this is Ninja1console.log ((ninja1.skulk () = = = Ninja1));
//Ninja2.skulk () returns the NINJA2 description this is Ninja2console.log ((ninja2.skulk () = = = Ninja2));
The code above proves that if a function is called as a constructor, the context of this function refers to the newly created object, which refers to NINJA1 and NINJA2
1.2.4 Using apply () and call ()
JS provides the Apply () and call () methods so that you can freely specify the context for the function.
by using apply (), you need to specify two parameters for apply (): One is a function context object, and one is an array of function arguments.
calling a function through call () requires arguments passed in: The function's context object, the function's argument list (the call () method does not necessarily have a number of 2 function arguments
function Juggle () {
var result = 0;
//Add the Parameters
For (var n =0;n<argument.length;n++) {
result + = Arguments[n];
}
//You can check the context of the juggle by using the result property
This.result = result;
}var ninja1 = {};var ninja2 = {};
//Use Apply () to bind the context of the juggle to NINJA1 and specify the parameter list as an array [1,2,3,4]
juggle.apply (ninja1,[1,2,3,4]);
//Use Call () to bind the context of the juggle to ninja2 and pass in the parameters of the method.
Juggle.call (ninja2,5,6,7,8);
//Verify Console.log (Ninja1.result); Console.log (Ninja2.result);
2. Overloading based on number of parameters
function Addmethod (OBJECT,NAME,FN) {
//Save the original function
var old = Object[name];
Object[name] = function () {
//If the number of formal parameters of the anonymous function matches the number of arguments, the function is called
if (fn.length = = arguments.length) {
return fn.apply (this,arguments);
}else{
//Otherwise call the original function
return old.apply (this,arguments);
}
}
}
/***************** test Code ***************************/
var ninjas = {
values:["Dean Edwards", "Sam Stephenson", "Alex Russell"]
};
//Declaration of a function without parameters
Addmethod (Ninjas, ' Find ', function () {
return this.values;
});
//function that declares a parameter
Addmethod (Ninjas, ' Find ', function (name) {
var ret = [];
For (var i = 0;i < this.values.length;i++) {
if (this.values . INDEXOF (name) = = 0) {
Ret.push (this.values);
}
}
return ret;
});
Functions that declare two parameters
Addmethod (Ninjas, "Find", Function (First,last)) {
var ret = [];
for (var i = 0;i < this.values.length;i++) {
if (this.values= = (First + "+ last)" {
Ret.push (this.values);
}
}
return ret;
}
Method for detecting Console.log (Ninjas.find (). Length = = 3);
Method for detecting a parameter Console.log (Ninjas.find ("Sam"). Length = = 1);
Methods for detecting two parameters Console.log (Ninjas.find ("Dean", "Edwards"). Length = = 1);
All functions have a length property, and the value of this property equals the number of values that are required to pass in the function declaration.
This method can realize the function overloading of multiple parameters through graceful closure. But this does not take into account the type of the parameter.
Addmethod () Each invocation produces a new anonymous function. And this new anonymous function contains an old object through the closure.
The old method contains the previous method. This is like an onion layer. Overloads of functions are implemented through closures that access old and FN.
3. New function wrapping old function of overloaded way
Define a wrapper function,
Receive three parameters: the context of the method that needs to be wrapped, the method name to wrap, the method that needs to be executed for the original method
function Wrap (object,method,wrapper) {
var fn = Object[method];
return Object[method] = function () {
To access FN via a closed packet
Return Wrapper.apply (This,[fn.bind (This)].concat (Array.prototype.slice.call (arguments)));
}
}
Test Code//////////////////////////////////////
var o = {};
Old method
O.OLDFN = function () {
Console.log ("This was old FN");
}
Use the Wrap method to overload the old method. The first parameter is the original function
Wrap (O, "OLDFN", function (OLDFN) {
Console.log ("This is new FN");
OLDFN ();
});
Call
O.OLDFN ();
First, the original method is saved in FN. When the new method is overloaded. The wrapper function before the new function executes. Returns a list of parameters that have been re-constructed. The first parameter in this parameter list is the original function to be overloaded.


Source: Blog Park

How do JavaScript closures implement overloading of functions?

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.