Home > Web Front-end > JS Tutorial > body text

Prototype Function object learning_prototype

WBOY
Release: 2016-05-16 18:50:16
Original
1131 people have browsed it

This object is an extension of function. The most important one is the bind method. The help document of prototype specifically says: Prototype takes issue with only one aspect of functions: binding. The wrap method is also very important. In class inheritance The mechanism uses the wrap method to call the method of the same name of the parent class.
argumentNames
bind
bindAsEventListener
curry
defer
delay
methodize
wrap

Copy code The code is as follows:

//Extend Function prototype through the extend method of Object object
Object.extend(Function.prototype, (function() {
var slice = Array.prototype.slice;
//Add args to 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 different Change the incoming parameter array and return a new array
function merge(array, args) {
array = slice.call(array, 0);
return update(array, args);
}
//Format the parameters of the function into an array and return
function argumentNames() {
var names = this.toString().match(/^[s(]*function[^(] *(([^)]*))/)[1]
.replace(///.*?[rn]|/*(?:.|[rn])*?*//g, ' ')
.replace(/s /g, '').split(',');

return names.length == 1 && !names[0] ? [] : names;
}
//Bind the context of the execution function to 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 , a);
}
}
//Basically similar to bind, that is, ensuring 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, a);
}
}
//curry is the name of a mathematician. The function of this method is to continuously pass in parameters. You will know by looking at 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, a);
}
}
//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 to implement a simple AOP function
function wrap(wrapper) {
var __method = this;
return function() {
var a = update([__method.bind(this)], arguments);
return wrapper.apply(this, a);
}
}
//Display the current context as the first parameter of 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, a);
};
}
//Return external callable function
return {
argumentNames: argumentNames,
bind: bind,
bindAsEventListener: bindAsEventListener,
curry: curry,
delay: delay ,
defer: defer,
wrap: wrap,
methodize: methodize
}
})());

update, merge method: because it is I won’t go into details about the internal methods. You can basically understand the
argumentNames method by looking at the source code:
basically uses regular expressions to propose the parameter list in the method, and deletes spaces and some Special characters, then use ',' to split, and finally return the parameter array. I don't understand what is the use of the condition of finally returning names.length == 1? I gave it a try and it had no effect. If you know anything, tell me. Let’s take a look at an example:
Copy code The 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 parameters passed in. At least one context parameter must be passed in. If the bind() method is called directly, the original function object will be returned. It's the same as not calling it.
The prototype of the bind method is like this: bind(thisObj[, arg...]) -> Function. The first parameter can be followed by optional parameters. In the bind method, the args variable is used to store everything except the first parameter. All other parameters except one parameter: args = slice.call(arguments, 1);
var __method = this. This sentence means to set the __method variable to the current function. It will be clearer through examples. These:
Copy code The 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(); }
//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 don’t call f() inside the runFx function, but call obj.fx() directly outside Then the result will be 'A nice demo'.
In fact, if we write like this: var f=obj.fx;f(); we will also get 'I am such a beautiful window!'.
Through the above example, we should be able to see the concept of context:
obj.fx(); //The context is: obj
f(); //The context is: window
You can see The context is actually the object before the last '.'. If the function is called directly, the context is window
*/

Finally, an anonymous function applied to the context is returned.
Note: The arguments in var a = merge(args, arguments); and the arguments in args = slice.call(arguments, 1); 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(', '));
}
};
//[1,2,3] here is slice.call(arguments, 1); the arguments inside
var fx2 = obj.fx.bind(obj, 1, 2, 3);
//[4,5] here is 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 is 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 the code The 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);
//==================== ===


curry method:
I personally feel that the example given in the help document for this method is not good. Here is another example, which will be clear at a glance:
Copy code The 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:
Basically, it is a simple encapsulation of window.setTimeout. The time unit is seconds. Take a look at the example:
Copy the 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, letting 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.
This sentence means: var a = update([__method.bind(this)], arguments); Just pass the wrapped function into the wrapping function as the first parameter. Take a look at the example:
Copy the code The code is as follows:

function wrapped(){
alert('wrapped');
}
//You can call the original function before or after the wrapper. Isn’t it a bit like 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 methodized has been methodized, and checks through the internal variable this._methodized,
Finally What the methodize function returns is actually this._methodized.
This sentence: var a = update([this], arguments); is the key. It can be seen that this is passed as the first parameter to the original function. Just look at the example and you will 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 The method
fn(object, 'bar');
object.value //-> 'bar'
//After calling methodize, it can be seen that the first parameter target of the fn function becomes object
object.fnMethodized = fn.methodize();
object.fnMethodized('boom!');
object.value //-> 'boom!'
Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!