1. application case:
Copy codeThe Code is as follows:
Var Mouse = function (){
// Look! No that = this!
This. position = [0, 0];
If (document. addEventListener ){
Document. addEventListener ('mousemove ',?); // This. move?
} Else if (document. attachEvent ){
Document. attachEvent ("onmousemove ",?); // This. move? How to put it in
}
};
Mouse. prototype. move = function (arg1, arg2, event ){
Event = window. event | event;
Var x = event. pageX | event. offsetX,
Y = event. pageY | event. offsetY;
This. position = [x, y];
This. log (arg1, arg2 );
};
Mouse. prototype. log = function (arg1, arg2 ){
Console. log (arg1 + "," + arg2 );
Console. log (this. position );
};
New Mouse ();
You know above '? What are you doing there? I want to bind my move METHOD TO THE mousemove of the document, but it is difficult. In this case, Mouse. prototype. move
This in will not point to the Mouse object. I believe you often encounter this problem. Maybe you knew how to solve it, but is there a faster and simpler way? The answer is:
Function. prototype. bind () is a magic thing, but ie6 7 8 does not support it. Generally, modern browsers support it. What we need to do next is to imitate it,
Of course, we need to imitate such a good method. For how to imitate it, see the original method of nothing below.
Copy codeThe Code is as follows:
(Function (){
Var proxy = function (fn, target ){
Var proxy = function (){
If (2 <arguments. length) {// when a parameter exists for the function to be proxy
Var privateArgs = Array. prototype. slice. call (arguments, 2 );
// Get it from the second one, [this, bound object, parameter list]
Return function (){
Var args = Array. prototype. slice. call (arguments );
--> Here, the arguments is not the same as the outside. This is the arguments object inside the function to be proxy,
For example, the arguments [0] = [object Event] of the move function is the e parameter in the Event.
Array. prototype. unshift. apply (args, privateArgs );
--> The uploaded parameters are added here, and the parameter format is the same as that of native bind.
//-> And put private parameters in the front, such as a = new Mouse (); a. move );
// If this move method does not have a parameter, it means prototype. move = fn () {arguments },
// The input parameter, arguments. length = 3,
// Arguments [0] = 1, arguments [1] = 2, arguments [2] = [object event].
Return fn. apply (target, args );
}
// The reason for this complexity is that the proxy function can directly access arguments. For example, I directly use it instead of passing parameters to the proxy function.
// This arguments will contain the same object as the arguments of native Function. prototype. bind,
// The code here is esoteric because you don't understand what arguments are in the native bind here. If you know it, you will know why I bound my arguments.
// The main purpose of doing so much is to make the arguments in the function you are proxy to be consistent with the arguments object in function. prototype. bind.
}
Return function (){
Return fn. apply (target, arguments );
}
}
Return proxy. apply (null, arguments );
};
/* Supports native use of native */
Function. prototype. bind = Function. prototype. bind |
Function (target) {// here this refers to the function to be proxy
If (1 <arguments. length ){
Var args = Array. prototype. slice. call (arguments, 1); // retrieve the parameter list
Args. unshift (this, target); // this args is eventually changed to [this, bound object, parameter list]
Return proxy. apply (null, args );
-- If you directly use proxy (args), The args becomes a parameter of the proxy function and an error is reported,
In fact, this mainly involves separate task processing. The proxy only cares about how the proxy and the parameters are passed to the proxy. If the proxy has no parameters, it will directly;
Return proxy (this, target) --> return fn. apply (target, arguments); the answer on the 17th floor.
--> It is estimated that everyone will make the same mistake as the 17th floor. The reason for this complicated operation of the arguments object is to ensure that the arguments object is passed into the proxy function and that it is not invalid.
}
Return proxy (this, target );
};
})();
Why does the above Code always return back to the proxy, because in this way you can call this. move. bind (this,) () and then the function will be executed immediately!
With the above code, we can easily implement it "? "No. What code should I write here? ^ _ ^, simple.
Copy codeThe Code is as follows:
If (document. addEventListener ){
Document. addEventListener ('mousemove ', this. move. bind (this, 1, 2 ));
} Else if (document. attachEvent ){
Document. attachEvent ("onmousemove", this. move. bind (this, 1, 2 ));
}
Is it very easy for this method to point to other objects when an event is to be added and then called in the future ..
It's hard to understand the above Code.
Copy codeThe Code is as follows:
Var a = function (){
Console. log (arguments [0]); // 1
Console. log (arguments [1]); // 2
Console. log (this. key1 );
// If you bind parameters in this way, you can only list them in the same way as the native bind. This is so simple,
};
Var B = {
Key1: "value1"
};
A. bind (B, 1, 2 )();
I think this is a mistake that many people make. The Code is as follows:
Copy codeThe Code is as follows:
Function. prototype. bind = function (target ){
Var self = this;
Return function (){
Return self. apply (target, arguments); // The arguments here cannot be passed in.
}
}
Var a = function (){
Console. log (arguments. length); // In this case, the arguments parameter is invalid.
// Arguments. length = 0.
Console. log (this. key1 );
};
Var B = {
Key1: "value1"
};
A. bind (B, [1, 2], 3) (); // you can see from here that the expected arguments. length = 2
// This is why I am eager to operate the arguments parameter.
// I know most people here will think right, but you are wrong. You still have to think about it on the 17th floor.
Source code without comments,
Copy codeThe Code is as follows:
(Function (){
Var proxy = function (fn, target ){
Var proxy = function (){
If (2 <arguments. length ){
Var privateArgs = Array. prototype. slice. call (arguments, 2 );
Return function (){
Var args = Array. prototype. slice. call (arguments );
Array. prototype. unshift. apply (args, privateArgs );
Return fn. apply (target, args );
}
}
Return function (){
Return fn. apply (target, arguments );
}
}
Return proxy. apply (null, arguments );
};
/* Supports native use of native */
Function. prototype. bind = Function. prototype. bind |
Function (target ){
If (1 <arguments. length ){
Var args = Array. prototype. slice. call (arguments, 1 );
Args. unshift (this, target );
Return proxy. apply (null, args );
}
Return proxy (this, target );
};
})();
This article is followed by the previous article. I will introduce a detailed column.
Let's take a look at the column. This blog does not have time to build a gorgeous layout. I only want simple code, which is only used by js Code enthusiasts.
Copy codeThe Code is as follows:
Var Mouse = function (){
If (document. addEventListener ){
Document. addEventListener ('mousemove ', this. move. bind (this, 1, 2, [3, 4]);
} Else if (document. attachEvent ){
Document. attachEvent ("onmousemove", this. move. bind (this, 1, 2, [3, 4]);
}
};
Mouse. prototype. move = function (){
Console. log (arguments [arguments. length-1]. clientX );
};
The output result of arguments is a good explanation of the above Code. If you do not understand the above Code, please use the new columns for understanding.
Copy codeThe Code is as follows:
Var privateArgs = Array. prototype. slice. call (arguments, 2 );
// Private parameter, indicating the proxy parameter. Here 1, 2, [3, 4]
Return function (){
Var args = Array. prototype. slice. call (arguments );
// The parameters here represent the parameters of the agent, such as e in the event Function
Array. prototype. unshift. apply (args, privateArgs );
// Here, the parameters of the two are merged, and the private parameters are in the front to be consistent with the native Parameter order.
Return fn. apply (target, args );
// Include 1, 2, [3, 4] e in the merged parameters and apply
}
Well, here, you will find a good js technique, that is, not compatible with processing e = window. event | e, directly use arguments [arguments. length-1] indicates compatibility.
All browser event e objects save a lot of time for code and thinking,
The reason for writing this code is that you want to have a real understanding of the js Code and know where the true charm of js is. If you really understand this article, at least you know what arguments is.
What's going on? This blog is so bad that it only has simple code and is suitable for js code lovers to learn.
In fact, the true charm of js is more than that. With the above examples and instructions, I believe you should know about it too well. If you don't know more about the demo, you will know about it.
A js enthusiast will post some fresh code for you to learn from time to time. This blog aims to learn the essence of js Code together.