-1

In following example I have a couple of surprises:

I am sad, people not even reading question properly before voting it down. JSFiddle wraps variables to set them local. Please, dont show it as a proof in this case! --- And, also someone who was extra clever removed my code and wrapped it in fiddle to show his Great Stupidity to next level!

Snippet:

this.a = 100;
var a = 200;

function b() {
  this.a = 300;
  setTimeout(function() {
    console.log(this.a)
  }, 0);
}
b();
console.log("Hello");
console.log(a);

Result:

enter image description here

Query:

  1. When setTimeout is 0, the first log must be 300. Why do I see Hello printed before? (As function b is executed before "console.log(Hello)".

  2. The 3rd log must have the value "200", as this.a in both lines refers to window.a as this refers to window object in both locations. variable a still hods value as 200.

  3. While chrome shows Hello, 300, 300 Fiddle shows Hello, 200, 300

Any explanations for these 2 phenomenons?

Note: JSfiddle wraps the code in function to set them as local variables, so dont consider it for the current example. Try out in Chrome!

Community
  • 1
  • 1
Deadpool
  • 7,811
  • 9
  • 44
  • 88

2 Answers2

1

As commented,

What is happening is OP is calling b(). This internally calls setTimeout. In it, OP updates this.a where this is pointing to window. Hence 300

Following is a sample where I have wrapped code in IIFE

(function() {
  this.a = 100;
  var a = 200;

  function b() {
    this.a = 300;
    setTimeout(function() {
      console.log(this.a)
    }, 0);
  }
  b();
  console.log("Hello");
  console.log(a);
})()

Explanation

// Here this points to window
this.a = 100;

// variables declared outside any functions are part of global scope (window)
var a = 200;

function b() {
  // this again points to window
  this.a = 300;
  setTimeout(function() {
    console.log(this.a)
  }, 0);
}
b();
console.log("Hello");
console.log(a);
Community
  • 1
  • 1
Rajesh
  • 24,354
  • 5
  • 48
  • 79
1

When setTimeout is 0, the first log must be 300. Why do I see Hello printed before? (As function b is executed before "console.log(Hello)".

No, all "timed out" function executions execute asynchronously. The execution is slotted into the next available time slot after your current snippet has finished. 0 simply schedules it very very soon, it doesn't make it a synchronous call.

The 3rd log must have the value "200", as this.a in both lines refers to window.a as this refers to window object in both locations. variable a still hods value as 200.

This very much depends on what this is initially. When executed in a plain Javascript environment where the initial this is window, all as refer to the same window.a, and the expected result is 300, because that's what it's set to before it's being logged the first time.

While chrome shows Hello, 300, 300 Fiddle shows Hello, 200, 300

The Fiddle environment is special and the initial this is not window.

deceze
  • 510,633
  • 85
  • 743
  • 889