JavaScript under dynamic This and dynamic binding instance code _javascript tips

Source: Internet
Author: User

Then the function is broken into two parts stored in the object, one is its function name (key), one is the function body (value), then the function of this generally refers to the object of the function. But that's general, when we call a function globally, we don't see the caller, or it's window. However, the function declaration does not actually bind to any objects, so we can use call to apply these methods to set the caller. A simple example of

:
[script]
<script>
window.name = "Window";
var run = function () {
alert ("My name is" + this.name);
}
Run ();
</script>
[/html]
Here you cannot say that run is a property of window, but it is actually called by the window property. In essence most of the things that are exposed to the top are taken over by window. They are copied to the window object when they need to be invoked (although Windows does not inherit objects in IE), there is a difference in performance between window[' xxx ' and window.xxx. This is internal realization, not to delve into.
Another example, binding to an explicit object

<script> window.name = "Window"; Object = {Name: ' object ', Run:function () {alert (' My name is ' + this.name); } }; Object.run (); </script>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

The answer is obvious, this is always for its caller. But what if it's a little more complicated?
<script> window.name = "Window"; Object = {Name: ' object ', Run:function () {var inner = function () {alert ("My name is" + this.name); } inner (); } }; Object.run (); </script>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

Although it is defined inside the object, although it is defined inside the run function, it pops up neither object nor run, because it is neither an object's property nor a run's property. It is loosely used in the scope of the run and cannot be invoked by the first two, only saved by the window. Windows and other native objects are saturated with all the scripts inside, pervasive, as long as where it is needed to contribute to the place, it is incumbent on. But usually we don't need it to be a disservice, and that requires two great tools of call and apply.
<script> window.name = "Window"; var object = {Name: ' object ', Run:function () {inner = function () {alert (this.name); } inner.call (this); } object.run (); </script>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

Call and apply is the difference between the first parameter of the form of the argument, call is one, aplly are placed on an array, in the case of ambiguous parameters, we can use arguments and array.slice easy to handle.
<script> window.name = "Window"; var cat = {name: "Cat"}; var dog = {name: "Dog", sound:function (word) {alert (this.name + word); } }; Dog.sound ("is pooping"); Dog.sound.call (Window, "is banking"); Dog.sound.call (Dog, "is banking"); Dog.sound.apply (CAT, ["miaowing"]); </script>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

This prototype developer has a very well-known function to come out, bind! the following is one of its simplest version:
Copy Code code as follows:

var bind = function (context, FN) {
return function () {
Return fn.apply (context, arguments);
}
}

<script> window.name = "Window"; var cat = {name: "Cat"}; var dog = {name: "Dog", sound:function (word) {alert (this.name + word); } }; var bind = function (context, FN) {return function () {return fn.apply (context, arguments); } var Sound2 = bind (Window,dog.sound); Sound2 ("is banking"); var Sound3 = bind (Cat,dog.sound); Sound3 ("miaowing") </script>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

However, in order to face more complex situations, suggest the following version.
Copy Code code as follows:

function bind (CONTEXT,FN) {
var args = Array.prototype.slice.call (arguments, 2);
return args.length = = 0? function () {
Return fn.apply (context, arguments);
}: Function () {
Return fn.apply (Context, args.concat.apply (args, arguments));
};
};

It also has a twin brother called Bindaseventlistener, binding event object, there is nothing to say.
Copy Code code as follows:

var Bindaseventlistener = function (context, FN) {
return function (e) {
Return Fn.call (the context, (e| | window.event));
}
}

Version of prototype
Copy Code code as follows:

Function.prototype.bind = function () {
if (Arguments.length < 2 && (typeof arguments[0]=== ' undefined '))
return this;
var _slice = Array.prototype.slice
var __method = this, args = _slice.call (arguments,0), context = Args.shift ();
return function () {
Return __method.apply (the context, Args.concat (_slice.call (arguments,0));
}
}

<script> Function.prototype.bind = Function () {if (Arguments.length < 2 && (typeof arguments[0]=== ' und Efined ') return to this; var _slice = Array.prototype.slice var __method = this, args = _slice.call (arguments,0), context = Args.shift (); return function () {return __method.apply (context, Args.concat (_slice.call (arguments,0)); } var sound2 = dog.sound.bind (window); Sound2 ("is banking"); var sound3 = Dog.sound.bind (cat); Sound3 ("miaowing") </script>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

The BIND function is so useful that Google has already added it to the prototype of the function (in addition to inherits,mixin and partial).
Copy Code code as follows:

In the Chrome
var a = function () {};
Alert (A.bind)

There is bound to have binding, or to peel better! For example, the method of generalization of native objects is that we can't get them out by traversal.
<script> for (var i in Array) {alert (i + ":" + Array[i])} for (Var i in Array.prototype) {alert (i + ":" + Arra Y.prototype[i])} </script>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

This is what you need to remove them:
Copy Code code as follows:

var _slice = Array.prototype.slice;
function Unbind (FN) {//First step get generalization method
return function (context) {//The second part is to be called again with the corresponding native object!
Return fn.apply (Context, _slice.call (arguments, 1));
};
};

Examples have been given before, see article
Summarize:
The value of this depends on how the function is invoked, a total of four species,
If a function is a property of an object, when the funtion is invoked, the value of this is the object. If a function calls an expression that contains a period (.) or a value of [],this] that is a period (.) or an object before []. In the case of Myobj.func and myobj["Func", this is myobj when Func is invoked.
If a function is not a property of an object, the value of this is the global object when the function is invoked. When a function contains internal function, it is easy to cause errors if you do not understand the correct meaning of this. This is because the this value of the internal function is not the same as the this value of the function outside it. The workaround is to save the this value of the external function in a variable and use it in the internal function to find the variable.
If you use new before a function, a new object is created and the funtion is called, and the value of this is the newly created object. such as function User (name) {this.name = name}; var user1 = new User ("Alex"); , by calling New User ("Alex"), a new object is created, referenced by User1, and the User function is invoked, setting the attribute named name to the User1 object, which is the value of Alex.
You can specify the value of this at the time it is invoked by using the apply and call methods of the function. The first argument to apply and call is the value of this that you want to specify. Because they exist, we are able to create a variety of useful functions.

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.