Confusion over the 'this' keyword in Javascript

I can argue that the 'this' keyword is the most confusing part of Javascript for anyone coming from languages ​​like C #.

I read a lot about this on the Internet and on StackOverflow. for example here and here .

I know that the keyword 'this' will be context bound. and in the constructor function, it will be bound to the created object, and when there is no immediate context, it will be bound to the global object (for example, to the window)

I know all this, but the confusion is still not completely cleared; So the best way to understand is to check the codes.


So, I decided to write a little code, and I was surprised at how confused the this keyword is.

here is the code i tested:

  function sayHi(name){ var tt = name; return { ss: tt, work: function(anotherName){ alert ("hiiiii " + anotherName); } }; } //this method invocation has no effect at all right now sayHi("John"); var hi2 = new sayHi("wallace"); hi2.work("May"); alert(hi2.ss); 

as expected, a warning window will appear (Hiiiiii May), then (Wallace). Notice the line sayHi("John"); has no effect.

and now the confusion will start when I replace one thing ONLY (change var tt => this.tt):

  function sayHi(name){ //this is the ONLY change I did. this.tt = name; return { ss: tt, work: function(anotherName){ alert ("hiiiii " + anotherName); } }; } // Now this line invocation will be problematic sayHi("John"); var hi2 = new sayHi("wallace"); hi2.work("May"); alert(hi2.ss); 

the result surprised me when he warned mthod (Hiiiiiii May) and then (John) not (wallace);

therefore, I had the idea to comment on the sayHi("John"); line sayHi("John"); , but this led to the fact that all the code was not functional and did not work.

demo

I know this might be a newbee question. But it really is confusing here, and I tried to read a lot of articles and questions, but I missed this point.

Why sayHi("John"); string sayHi("John"); sets hi2.ss to John? and why it violates the code when it is deleted; although we call the sayHi method using the new afterward ??

+7
javascript this
source share
3 answers

At the first call sayHi("John"); , this will point to the global window object. This means that this.tt = name actually creates the tt global variable.

Then when you call new sayHi("wallace"); , this correctly points to a new instance of sayHi , but you are returning another object instead of allowing new naturally return an instance.

If you look closely at your object literal, you define ss as ss: tt, Since you are not using this.tt and there is no tt character in the constructor area, then the value will be resolved as a global variable (which was previously set to John ).

+3
source share

Since you assign the parameter β€œname” to the property of the object referenced by this (which in this case will be window ), your subsequent reference to β€œtt” in this object literal will be associated with the β€œtt” of the global object, since this is the next span.

Your first call to sayHi is made without the new operator, so in this call this will refer to the global object ( window ). The first line in the second version

 this.tt = name; 

therefore set window.tt to "John".

The next call is made using the new operator. Because of this, this in function refers to a newly created object. Line

 this.tt = name; 
Thus,

really has no effect on anything because the function returns a different object in all cases. Last line of your test:

 alert(hi2.ss); 

says "John" because that is what is in window.tt . Why does it matter? Because "sayHi" returns an object with the property ("ss") set from the value of the "tt" symbol. The only "tt" in scope will be window.tt , which was returned the first time the function was called.

+6
source share

When calling the constructor function, if the return statement does not exist in the function, then this implicitly returned, otherwise the return value is returned and this simply ignored.

In your second example, you save the name argument as this.tt , but return another object. That is why everything does not work. Mostly use this or return a custom object, but don't do both.

+3
source share

All Articles