Volume "this"

I have a simple object, and I do not understand the concept (scope) of this , calling the functions of this object.

Why, in the last version (3), the call to show() (with the show() function inside the object without a parent) results in: "This is global", and not the internal variable title("Color Picker") ?

I have a vague idea that calling the popup.show() function after defining the useless variable show , this refers to a global object. Is this a logical explanation?

Code: http://jsbin.com/otuzac/1/edit .

 var title="'This' is global"; var popup={ dom_element:("#popup"), title :"Color Picker", prev_color :'#fff', set_color : function(color){ color=color || this.prev_color; //set the color return color; }, show :function(){ return("showing "+this.title); } }; var show=popup.show(); //Case 1: var show=popup.show() alert(show); //output "Color Picker" //Case 2: var show=popup.show() alert(popup.show()); //output "Color Picker" //Case 3: var show=popup.show !!! (no parent.) alert(show()); //output "This is global" 
+5
source share
5 answers

That this depends on how you call the function in which you use this .

1. call as a function

 functionName(); 

In this case, this will always refer to the global object (most often the window object).

Example

 a = 2; function XY(a) { this.a = a; this.b = function () { func(); }; function func () { console.log(this.a); } } var xy = new XY(1); xy.b(); //2 

Note

  • The example is a little constructed, but note that the func function is called simply by writing func(); . Therefore, even if your function is inside the constructor function ( XY ) and called from a function that is called as a method (see Clause 3), this still applies to the global object.

2. call with a new keyword

 var obj = new functionName(); 

In this case, this will refer to the newly created object.

Example

 a = 2; function XY(a) { this.a = a; } var xy = new XY(1); console.log(xy.a); //1 

3. call as a method

 obj.functionName(); 

In this case, this will refer to the object containing the function that you are calling.

Example

 a = 2; var xy = { a: 1, func: function() { console.log(this.a); } } xy.func(); //1 

4. call with apply

 functionName.apply(thisObj, argArray); 

In this case, this will be a new Object(thisObj) , with thisObj being the first argument to the apply function.

Example

 function xy (a,b) { console.log(this); } xy.apply({f:3}, [1,2]); //Object {f: 3} xy.apply("hello", [1,2]); //String {0: "h", 1: "e", 2: "l", 3: "l", 4: "o"} 

5. event handler call

As a Mifeet user suggested, events also change the context of this :

Events are a separate issue. They are not part of EcmaScript and are typically handled differently by different browsers. However, the differences regarding this not significant for IE> 8, as far as I know, nonexistent.

this will refer to the DOM element that triggered the event, unless you use the inline event handler. In this case, this will refer to the global object.

Example

 <button id="1" onclick="clickit()">click me</button> <!-- 0 --> <button id="2">click me</button> <button id="3">click me</button> <script> var button1 = document.getElementById("1"); var button2 = document.getElementById("2"); var button3 = document.getElementById("3"); id = "0"; window.clickit = function(){ console.log(this.id); }; button2.onclick = clickit; //2 button3.addEventListener("click", clickit, false); //3 </script> 

Event Notes

  • Internet Explorer prior to version 9 did not support addEventListener , but attachEvent . Using this function will also result in this related to the global object.
  • this , directly inside the HTML tag, will refer to the DOM element representing this tag. Therefore, <button id="1" onclick="clickit(this)">click me</button> will pass the DOM element to the clickit event clickit .

back to your case

In the first two cases, you call your function as a method, and in the latter case, you call it as a function. This is why in the latter case, this refers to a global object.

EDIT

I recently saw a very similar answer to a very similar question here on StackOverflow. Unfortunately, I could no longer find it, so I decided to send the answer myself. But if someone knows what I mean, just leave a comment, and I will gladly put a link to the original answer in my answer.

+5
source

In your case 1: var show=popup.show() calls the show function, which is defined in the popup. And the show function is this object, which refers to the pop-up object, and the pop-up object has its own header variable that calls the show function. why is he showing a "color picker" .

case 2: this is also the case for case 1, here you call the show function without using a variable. therefore the same way out.

case 3: In case of the third, you call the show function without reference to any object, as you do in cases 1 and 2. therefore, the document of the object object is used by default. and in the document, the value of the header '' This' is global " , so it shows you the result of " 'This' global . " and this refers to the document object.

Hope this will be helpful for you.

+3
source

This is because you are considering the show variable as a function. Make it simpler:

 function a(){ return "textA"; } var obj={ b: function(){ return "text b";} }; console.log(a); // will output the function object console.log(a()); // will call a then output the result of the function --> "textA" console.log(obj.b); //will output the function object same as console.log(a) console.log(obj.b()); // will call b then output the result of the function --> "text b" 

Now imagine that I am doing something like your third example:

 var anotherObj = a(); console.log(anotherObj()); // you try to treat the return of a() as a function. will not work --> "string is not a function " 

You can do this, for example:

 console.log(window[anotherObj]()); 

this will call a function called "textA". Full fiddle here

As for scope, this one refers to the window default. When launched inside an object, it will refer to this object if the function is not applied to something else.

+1
source

As explained by others, in the first two cases, you call the function in the popup object, so this refers to popup . In the third case, you call the function yourself, and not on the object, so this refers to the global scope ( window ). Also, in your example, you cannot use alert(show()); because show is not a function here, but a string.

If you want to get the desired result, you can use the following template (used by many frameworks, for example jQuery):

 var title="'This' is global"; (function() { var popup = { dom_element:("#popup"), title :"Color Picker", prev_color :'#fff', set_color : function(color){ color=color || this.prev_color; //set the color return color; }, show :function(){ return("showing " + popup.title); // refer to the local variable popup instead of this } }; window.popup = popup; // add the (now initialized) local variable popup to the global scope })(); // execute immediately var show=popup.show(); var showFn = popup.show; // You cannot use the result of popup.show() as a function because it a string //Case 1: alert(show); //output "Color Picker" //Case 2: alert(popup.show()); //output "Color Picker" //Case 3: alert(showFn()); // output "Color Picker" 

( Js bin )

+1
source

this always refers to the current object or context.
In case 2, this object pops up. This is why you see popup.title in the message.

What you effectively do in case 3 when you assign popup.show to show creates a handle to the window object to display (or at least the current area). Thus, for this handle, the window object. So now, if you call this handle, it will show the title , which you also registered in the window object.

You can set a context with a call and / or apply like this:

 var show=popup.show alert(show.call(popup)); 
0
source

Source: https://habr.com/ru/post/955602/


All Articles