Transferred from: http://blog.leapoahead.com/2015/08/31/understanding-js-this-keyword/
When writing JavaScript applications, we often use this
keywords. So this
how exactly does the keyword work? What are the good places in its design and what are the bad places? This article takes you to know this old friend comprehensively and systematically.
Xiaoming here is the subject , if not the subject, then the latter pronoun "he" will be meaningless. With a subject, a pronoun has something that can be referred to.
In the world of analogy to JavaScript, when we call a method of an object, we need to identify the object and then indicate the method to invoke.
var xiaoming = { 'Xiao Ming', run:function () { Console.log (' ${this. Name} seems happy '); },};xiaoming.run ();
In the example above, the subject of the xiaoming
method runtime is specified in line 8th. run
Therefore, run
we can use this
it instead of xiaoming
this object. Can see the this
role of pronouns.
Similarly, for a JavaScript class, after initializing it, we can also use a similar approach to understand that: when an instance of a class calls its method, it will be the subject, and its method will this
naturally become the pronoun of the subject.
classpeople {Constructor (name) {//when instantiating an object with the New keyword, it is equivalent to saying,//"Create a People class instance (subject), and the name of it (this) is ..."//So here's this is the newly created People class instance This. Name =name; } run () {console.log (' ${ This. Name} seems happy. ')}}//The new keyword instantiates a classvarXiaoming =NewPeople ('xiaoming'); Xiaoming.run ();
This is where I think the This keyword is designed to be wonderful! If the statement that invokes the method (line 16th of the code above) and the code of the method itself are connected, reading like English is actually completely fluent.
this
The binding
The subject of the sentence can be changed, for example, in the following scene, run
is assigned to the Fang ( xiaofang
) body, call xiaofang.run
, the subject becomes the Fang!
var xiaofang = { 'Xiao Fang',}; var xiaoming = { 'Xiao Ming', run:function () { console.log (' ${this. Name} seems happy '); = Xiaoming.run; // the subject becomes the Fang Xiaofang.run ();
In this case, the sentence is still fluent. So, very perfect!
But if Xiao Ming is very stingy, unwilling to lend the method to the run
Fang, this
it becomes the Fang, then how to do Xiao Ming? He can pass the Function.prototype.bind let run
run time this
forever for xiaoming himself
varXiaofang ={name:'Xiao Fang',};varXiaoming ={name:'Xiao Ming', Run:function () {console.log (' ${ This. Name} seems happy '); },};//After you bind Bob's Run Method (BIND), it returns a//function, but when the function is called, even if the subject is not xiaoming,//It's this is still xiaomingXiaoming.run =Xiaoming.run.bind (xiaoming); Xiaofang.run=Xiaoming.run;//Although the subject is Xiao Fang, but the last this or Xiao MingXiaofang.run ();
So what bind
this
is bind
the object of the same function after it has been repeated many times? You can try it out for yourself.
call
And
apply
The
Function.prototype.call allows you to specify the value of its this
when calling a function.
var xiaoming = {name: ' is ${today}, ${this .name} seems ${mood} ');} // // Subsequent arguments can be run.call (xiaoming, monday , ' happy )
Function.prototype.call
the function of Function.prototype.apply is exactly the same, and the difference is that apply
all the parameters required for the function call are placed in an array.
varXiaoming ={name:'Xiao Ming'};function Run (today, mood) {Console.log (' Today is${today}, ${ This. Name} seems ${mood} ');}//apply accepts only two parameters//The second argument is an array, and the elements of the array are sequentially//arguments that are called as runRun.apply (Xiaoming, ['Monday','Happy'])
call
apply
bind
What kind of behavior is it when it's mixed with the above? This is also left to everyone to verify themselves. However, in general, we should avoid mixing them, otherwise it will cause the code to check or debug when the value of difficult to track this
the problem.
When the method loses its subject,
this
No longer there?
In fact, you can find my words, when a function
call is a subject, it is a method ; When a function
call is made without a subject, it is a function . When a function runs, it has no subject, but its this
value is the global object. In the browser, that's window
. Of course, the premise is that the function has not been bind
, or is not, apply
call
called.
So function
what are the scenarios as functions?
First, the invocation of the global function is the simplest one.
function Bar () { Console.log (this// output: True}bar ();
A function expression called immediately (iife,immediately-invoked function expressions) also has no subject, so it is this
also a global object when called.
(function () { Console.log (this// output: True}) ();
However, when the function is executed under strict mode (Strict-mode), this is the call of the function undefined
. This is a very noteworthy point.
function Bar () { 'usestrict'; Console.log (' + String ' (this// output: undefined }bar ();
Non-visible calls
Sometimes you have no way to see how the function you define is called. Therefore, you have no way of knowing its subject. Here's an example of adding an event listener with jquery.
' window Val ' ; var obj = { 'obj val', foo:function () { $ ( ' #text '). Bind ('click', function () { Console.log (this. val) ); }};o Bj.foo ();
In the event's callback function (the anonymous function defined at line 6th), this
the value is neither window
, nor is obj
it, but the id
text
HTML element on the page.
var obj = { foo:function () { $ ('#text'). Bind (' Click ' , function () { Console.log (this = = document.getElementById ('text ' // Output: True }); }};o Bj.foo ();
This is because anonymous functions are called internally by jquery, and we do not know what the subject is when it is called, or whether the bind
value is modified this
by the function. Therefore, you need to be extra cautious when you give anonymous functions to other parts of the program.
If we want to use the value of obj in the callback function above, in addition to the val
direct write obj.val
, you can also use a new variable in the Foo method that
to save the foo
runtime this
value. This is a bit of a detour, so let's take a look at the example.
Window.val ='window Val';varobj ={val:'obj Val', Foo:function () {varthat = This;//Save this reference to that, where this is actually the obj$('#text'). Bind ('Click', function () {console.log (that.val);//output: obj val }); }};obj.foo ();
Another method is for the anonymous function bind
.
Window.val ='window Val';varobj ={val:'obj Val', Foo:function () {$ ('#text'). Bind ('Click', function () {Console.log ( This. val);//output: obj val}.bind ( This)); }};obj.foo ();
Summarize
The use of JavaScript this
is really strange, but if you use natural language to understand it, it's all in the way. Do you understand when you finish reading this article? Or are you asleep? Kiss...... Wake up......
If you have any questions, please feel free to discuss them in the comments section. Also, you are welcome to subscribe to my fortnightly below, and I will share interesting technology, products, and design pieces for you.
Understanding the This keyword in javascript with a natural language perspective