Prototype Function Object Learning _prototype

Source: Internet
Author: User
Tags aop wrapper
This object is a few extensions to the function, the most important of which is the bind method, Prototype's help document specifically said: Prototype takes issue with only one aspect of functions: Binding. Where The Wrap method is also important, within the class inheritance mechanism is the use of the Wrap method to invoke the same method of the parent class.
Argumentnames
Bind
Bindaseventlistener
Curry
Defer
Delay
Methodize
Wrap
Copy Code code as follows:

Extending the prototype of a function through the Extend method of object objects
Object.extend (Function.prototype, (Function () {
var slice = Array.prototype.slice;
Add the args to the array, and return the array, the internal method
function update (array, args) {
var arraylength = array.length, length = args.length;
while (length--) array[arraylength + length] = Args[length];
return array;
}
Basic and update methods, but does not change the incoming parameter array, returns a new array
function merge (array, args) {
Array = slice.call (array, 0);
Return update (array, args);
}
Format the parameters of the function into groups 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
function bind (context) {
if (Arguments.length < 2 && object.isundefined (arguments[0)) return to this;
var __method = this, args = Slice.call (arguments, 1);
return function () {
var a = merge (args, arguments);
Return __method.apply (context, a);
}
}
Basically the same as bind, is to ensure that the first parameter passed must be an 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, a);
}
}
Curry is the name of a mathematician, and the function of this method is to be able to pass through the parameters in succession, see the specific example below to know
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, a);
}
}
Simple encapsulation of 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 that will be invoked to achieve a simple AOP function
function Wrap (wrapper) {
var __method = this;
return function () {
var a = update ([__method.bind (this)], arguments);
Return wrapper.apply (this, a);
}
}
The method of the incoming call that displays the current context as the first argument
function Methodize () {
if (this._methodized) return this._methodized;
var __method = this;
return this._methodized = function () {
var a = update ([this], arguments);
return __method.apply (null, a);
};
}
Returns a function that can be called externally
return {
Argumentnames:argumentnames,
Bind:bind,
Bindaseventlistener:bindaseventlistener,
Curry:curry,
Delay:delay,
Defer:defer,
Wrap:wrap,
Methodize:methodize
}
})());

Update,merge method: Because it is internal method, not in detail, look at the source code can basically understand
Argumentnames Method:
The basic is to use regular expressions to propose the parameter list in the method, and delete the space and some special characters, and then use ', ' to split, and finally return the parameter array, I do not understand the last return names.length = = 1 What is the use of this condition? I tried, went to have no effect, know tell me. Here's a look at the example:
Copy Code code as follows:

var fn = function (foo, bar) {return foo + bar;};
Fn.argumentnames (); -> [' foo ', ' Bar ']
Prototype.emptyFunction.argumentNames (); -> []

Bind method:
First, the number of parameters to be passed in, at least a context parameter, if the bind () method is called directly, the original function object is returned. is equivalent to not calling the same.
The prototype of the Bind method is this: Bind (thisobj[, arg ...])-> Function, the first argument can be followed by an optional argument, and in the Bind method, the args variable is used to store all the other parameters except the first argument: args = Slice.call (arguments, 1);
var __method = This, which means that the __method variable is set to the current function, which is more clearly illustrated by the example:
Copy Code code 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 ();}
Where __method is the equivalent of obj.fx
var fx2 = obj.fx.bind (obj);
Runfx (OBJ.FX); I am such a beautiful window!
Runfx (FX2); A Nice Demo
/*
Here if we don't call F () in the Runfx function, but call obj.fx directly outside () then the result will be ' A nice demo '.
In fact if we write this: Var f=obj.fx;f (), it will also get ' I am such a beautiful window! '.
From the above example, we should be able to see the concept of context:
Obj.fx (); Context is: obj
f (); Context is: Window
You can see that the context is actually the last one '. ' The previous object, if the function is called directly, the context is window
*/

Finally, an anonymous function that is applied to the context contexts is returned.
Note: var a = merge (args, arguments); In this sentence the arguments and args = slice.call (arguments, 1); The arguments inside is not the same. Take a look at the example:
Copy Code code 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); Inside the arguments
var fx2 = Obj.fx.bind (obj, 1, 2, 3);
Here [4,5] is the merge (args, arguments); the arguments inside.
FX2 (4, 5);
Alerts the proper name, then "1, 2, 3, 4, 5"

Bindaseventlistener Method:
This method is similar to bind, the main difference 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 Code code 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:
The personal view of this method is that the example given on the help document is not good, and here is another example to see:
Copy Code code 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:
The basic is window.settimeout simple encapsulation, the time unit is seconds, look at the example:
Copy Code code 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 I, letting you easily build on Existi ng functions by specifying before and after behavior, transforming the return value, or even preventing the original funct Ion from being called.
var a = update ([__method.bind (this)], arguments) means to pass the wrapped function as the first argument to the wrapper function, and look at the example:
Copy Code code as follows:

function wrapped () {
Alert (' wrapped ');
}
You can call the original function before wrapper or call it later, isn't it a bit 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 the another function that.
Pushes this to the original function as the the-the-argument.
This method first checks whether the method that will be Methodize has been methodize, through the internal variable this._methodized to do the check,
The last Methodize function returns is actually this._methodized.
This sentence: var a = update ([this], arguments), is the key, you can see this as the first parameter to the original function. Take a look at the example and you'll see:
Copy Code code as follows:

Start off with a simple function which is does an operation
On the target object:
var fn = function (target, foo) {target.value = foo;}; var object = {};
The original method
fn (object, ' Bar ');
Object.value//-> ' Bar '
After calling Methodize, you can see that the first parameter target of the FN function becomes object
object.fnmethodized = Fn.methodize ();
Object.fnmethodized (' boom! ');
Object.value//-> ' boom! '

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.