Prototype Function object Learning

Source: Internet
Author: User

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
Copy codeThe Code is as follows:
// Extended the Function prototype through the extended 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. You can basically understand the source code.
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 codeThe Code is as follows:
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 the bind () method is called directly, the original function object will be returned. It is equivalent to not calling.
The prototype of the bind method is as follows: 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 indicates that the variable _ method is set as the current function. It is clearer through examples:
Copy codeThe Code is as follows:
Var obj = {
Name: 'A nice demo ',
Fx: function () {alert (this. name );}
};
Window. name = 'I am such a beautiful window! ';
Function runFx (f) {f ();}
// The _ 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, but call obj. fx () outside, the result will be '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 above example shows the concept of context:
Obj. fx (); // The context is: obj
F (); // The context is window.
It can be seen that the context is actually the object before the last '.'. 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 codeThe Code is as follows:
Var obj = {
Name: 'A nice demo ',
Fx: function (){
Alert (this. name + '\ n' + $ A (arguments). joi (','));
}
};
// Here [1, 2, 3] Is slice. call (arguments, 1 );
Var fx2 = obj. fx. bind (obj, 1, 2, 3 );
// Here [] is the arguments in merge (args, 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:
It is basically a simple encapsulation of window. setTimeout. The unit of time is seconds. Let's take a look at the example:
Copy codeThe 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 used by methodize has passed methodize, and performs the check through 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 codeThe 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, we can see that the first parameter of the fn function, target, is changed to object.
Object. fnMethodized = fn. methodize ();
Object. fnMethodized ('boom! ');
Object. value //-> 'boom! '

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.