This object is an extension of the function. The most important thing is the bind method. Prototype's help document specifically says: Prototype takes issue with only one aspect of functions: binding. the wrap method is also very important. In the class inheritance mechanism, the wrap method is used to call the same name method of the parent class.
Argumentnames
Bind
Bindaseventlistener
Curry
Defer
Delay
Methodize
Wrap
CopyCode The Code is as follows: // extend the function prototype through the extend method of the object
Object. Extend (function. prototype, (function (){
VaR slice = array. Prototype. Slice;
// Add ARGs to the end of array and return array, internal Method
Function Update (array, argS ){
VaR arraylength = array. length, length = args. length;
While (length --) array [arraylength + Length] = ARGs [length];
Return array;
}
// Basically the same as the update method, but does not change the input parameter array, returns a new array
Function Merge (array, argS ){
Array = slice. Call (array, 0 );
Return Update (array, argS );
}
// Format the function parameters into an array and return
Function argumentnames (){
VaR names = This. tostring (). match (/^ [\ s \ (] * function [^ (] * \ ([^)] *) \)/) [1]
. Replace (/\/\/.*? [\ R \ n] | \/\*(? :. | [\ R \ n]) *? \ * \ // G ,'')
. Replace (/\ s +/g, ''). Split (',');
Return names. Length = 1 &&! Names [0]? []: Names;
}
// Bind the context of the execution function to the context
Function BIND (context ){
If (arguments. Length <2 & object. isundefined (arguments [0]) return this;
VaR _ method = This, argS = slice. Call (arguments, 1 );
Return function (){
VaR A = merge (ARGs, arguments );
Return _ method. Apply (context, );
}
}
// Basically similar to bind, that is, ensure that the first parameter passed in must be the event object
Function bindaseventlistener (context ){
VaR _ method = This, argS = slice. Call (arguments, 1 );
Return function (event ){
VaR A = Update ([event | window. event], argS );
Return _ method. Apply (context, );
}
}
// Curry is the name of a mathematician. The function of this method is to continuously pass in parameters. You can see the specific example below.
Function curry (){
If (! Arguments. Length) return this;
VaR _ method = This, argS = slice. Call (arguments, 0 );
Return function (){
VaR A = merge (ARGs, arguments );
Return _ method. Apply (this, );
}
}
// Simple encapsulation of the window. setTimeout Function
Function delay (timeout ){
VaR _ method = This, argS = slice. Call (arguments, 1 );
Timeout = timeout * 1000
Return window. setTimeout (function (){
Return _ method. Apply (_ method, argS );
}, Timeout );
}
// Equivalent to delay (0.01)
Function defer (){
VaR ARGs = Update ([0.01], arguments );
Return this. Delay. Apply (this, argS );
}
// Use wrapper to wrap the function to be called and implement a simple AOP Function
Function wrap (wrapper ){
VaR _ method = this;
Return function (){
VaR A = Update ([_ method. BIND (this)], arguments );
Return wrapper. Apply (this, );
}
}
// Use the current context as the first parameter to display the incoming call Method
Function methodize (){
If (this. _ methodized) return this. _ methodized;
VaR _ method = this;
Return this. _ methodized = function (){
VaR A = Update ([this], arguments );
Return _ method. Apply (null, );
};
}
// Return externally callable Functions
Return {
Argumentnames: argumentnames,
BIND: bind,
Bindaseventlistener: bindaseventlistener,
Curry: curry,
Delay: delay,
Defer: Defer,
Wrap: Wrap,
Methodize: methodize
}
})());
Update, merge method: because it is an internal method, it is not detailed.Source codeCan be understood basically
Argumentnames method:
Basically, a regular expression is used to propose the parameter list in the method, delete spaces and some special characters, separate them with ',', and return the parameter array. I don't understand, and finally return names. length = 1 what is the use of this condition? I tried it and it didn't affect me if I went there. Tell me what I know. The following is an example:Copy codeCode: var fn = function (Foo, bar) {return Foo + bar ;};
FN. argumentnames (); //-> ['foo', 'bar']
Prototype. emptyfunction. argumentnames (); //-> []
bind method:
first, determine the number of passed parameters. At least one context parameter must be input. If you call the BIND () method directly, then the original function object is returned. It is equivalent to not calling.
the bind method is prototype: BIND (thisobj [, Arg...]) -> function. The first parameter can be followed by an optional parameter. In the bind method, argS variables are used to store all parameters except the first parameter: ARGs = slice. call (arguments, 1);
VaR _ method = this, which means to set the _ method variable to the current function, the example shows more clearly: copy Code the code is as follows: var OBJ = {
name: 'A Nice demo',
FX: function () {alert (this. name) ;}< BR >};
window. name = 'I am such Beautiful Window! ';
function runfx (f) {f () ;}< br> // Where _ method is equivalent to OBJ. FX
var fx2 = obj. FX. BIND (OBJ);
runfx (obj. FX); // I am such a beautiful window!
runfx (fx2); // A Nice demo
/*
if we do not call f () in the runfx function, we call OBJ directly outside. the result of FX () is 'a nice demo '.
In fact, if we write var F = obj. FX; F ();, we will also get the 'I am such a beautiful window! '.
the preceding example shows the concept of Context:
obj. FX (); // The context is OBJ
F (); // The context is window
. You can see that the context is actually the last '. 'The previous object. If a function is called directly, the context is window
*/
finally, an anonymous Function Applied to the context is returned.
Note: var A = merge (ARGs, arguments); the arguments and ARGs = slice. Call (arguments, 1) in this sentence are different. Take a look at the example: copy the Code the code is as follows: vaR OBJ = {
name: 'A Nice demo',
FX: function () {
alert (this. name + '\ n' + $ A (arguments ). joi (',');
}< BR >};
// here [1, 2, 3] is slice. call (arguments, 1); arguments
var fx2 = obj. FX. BIND (OBJ, 1, 2, 3);
// here [] is merge (ARGs, arguments); arguments
fx2 (4, 5);
// alerts the proper name, then "1, 2, 3, 4, 5"
Bindaseventlistener method:
This method is similar to bind. The main difference is in this sentence: var A = Update ([event | window. event], argS); always ensure that the first parameter of the bound function is the event object. Take a look at the example:Copy codeThe Code is as follows: var OBJ = {Name: 'A Nice demo '};
Function handler (e ){
VaR DATA = $ A (arguments );
Data. Shift ();
Alert (this. Name + '\ nother ARGs:' + data. Join (','));}
Handler. bindaseventlistener (OBJ, 1, 2, 3 );
// ======================================
<Input type = "button" value = "button" onclick = "handle ()"/>
Curry method:
I personally think that the example provided in the help document is not good. The following is another example, which can be understood at a Glance:Copy codeThe Code is as follows: var F = function () {alert (array. Prototype. Slice. Call (arguments, 0). Join (''))};
F. Curry ('I). Curry ('am'). Curry ('Never-online'). Curry ('HTTP: // www.never-online.net ')();
// I am never-Online http://www.never-online.net
delay and defer Methods:
window is used. setTimeout is a simple encapsulation in seconds. For example, copy Code the code is as follows: // clearing a timeout
var id = element. hide. delay (5, 'foo');
window. cleartimeout (ID);
Wrap method:
Returns a function "wrapped" around the original function.
Function # wrap distills the essence of Aspect-oriented programming into a single method, leader you easily build on existing functions by specifying before and after behavior, transforming the return value, or even preventing the original function from being called.
VaR A = Update ([_ method. BIND (this)], arguments); Means to pass the encapsulated function as the first parameter to the packaging function. Let's take a look at the example:Copy codeThe Code is as follows: function wrapped (){
Alert ('wrapped ');
}
// You can call the original function or call it later before wrapper. Is it a bit of AOP?
VaR wrapper = wrapped. Wrap (function (oldfunc, Param ){
// Oldfunc ()
Alert (PARAM );
Oldfunc ();
});
// Wrapper, wrapped
Wrapper ("wrapper ");
methodize method:
takes a function and wraps it in another function that, at call time,
pushes this to the original function as the first argument.
This method first checks whether the method to be methodize has passed methodize and uses the internal variable this. _ methodized:
the final result returned by the methodize function is this. _ methodized.
var A = Update ([this], arguments); is the key. We can see that this is passed to the original function as the first parameter. Take a look at the example to understand: copy Code the code is as follows: // start off with a simple function that does an operation
// on the target object:
var fn = function (target, foo) {target. value = Foo ;}; var object ={};
// original method
FN (object, 'bar');
object. value //-> 'bar'
// after calling methodize, the first target parameter of the FN function is changed to an object.
object. fnmethodized = FN. Methodize ();
object. fnmethodized ('boom! ');
object. Value //-> 'boom! '