In this code, why are foo and this.foo related to other things?

Here is the code:

for (var i = 0; i < 10; i++) { setTimeout(function() { console.log(i); //prints 9 10 times console.log(this.i); //prints 0, 1, 2...9 }.bind({i:i}), i * 1000); } 

Why do i and this.i refer to different things?

Contrast this with a bit of code running in a global scope:

 var x = 5; console.log(x); console.log(this.x);//both will print 5 

Here the scale was global, and the context too. A variable declaration sets a property with the same name in a global context. On the other hand, this does not occur within the scope of the function.

 var a = function() { var x = 5; console.log(x); //5 console.log(this.x); //undefined console.log(i); //undefined console.log(this.i); //10 }.bind({i: 10}); a(); 

Even if we pass the global context to a local scope, declaring a variable inside a function does not set it as a property of the global context.

 var a = function() { var x = 5; console.log(x); //5 console.log(this.x); //undefined }.bind(window); a(); console.log(x); //undefined console.log(this.x); //undefined 

I'm trying to say the following: in a global scope, declaring a variable changes the global context . But in the area of functions, the declaration does not change the context of the function , regardless of the context. Why?

+6
source share
2 answers

This helps a lot when you think that the global scope is in the window. So you can say that global runs are in the context of the window. So really:

 var x = 5; console.log(x); console.log(this.x);//both will print 5 

The last line of this has window , so you run console.log(window.x) .

When you use bind , you change the this link inside the "bound" function. For instance:

 var x = 10; function log() { console.log(this.x); } log(); // logs 10 log.bind({x: 20})() // logs 20 

The bind call made this inside the log reference to the anonymous object that we created with {x: 20} . You can also do this:

 var myObject = {x: 50}; log.bind(myObject)(); // logs 50 
+2
source

Thinking about it a bit more, this behavior makes sense. Thanks to everyone who commented and replied. It helped me think this thing up a bit more.

  • Starting with the basics, in JavaScript, the scope of a variable is limited to the function in which it is defined.
  • In the global scope, var declares var as a property of the global context (excellent)
  • If we wanted the same behavior in the scope of functions, the var declaration would change the function context object. But this has the following problems:

    a. If the function context is some kind of object, each var declaration inside the function will be set as a property of the object. So this will happen:

The function has an object context:

 //if var declarations inside functions modified context //this doesn't happen in reality var ctx = {b: 5}; var a = function() { var c = 7; this.b = 10; }.bind(ctx); a(); console.log(ctx.b); //10, as expected console.log(ctx.c); //7, wtf? I never set this 

b. If the function context is not defined, its context is a global object. We already know that. But if var declarations in functions are allowed to change context in the same way var var declarations do in the global scope, then the functional scope becomes meaningless.

The function has a global context:

 function a() { var b = 5; this.c = 10; //this refers to window. it is this function context } a(); console.log(b); //outputs 5 if function vars could modify context, which means functional scope is dead console.log(c); //outputs 10, as expected 

This is why var works differently in and out of functions.

0
source

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


All Articles