-2

After reading the reply to my comment on the linked post, I decided to test things out with regards to the window object and global scope. I read some other questions regarding how to reference the original function such as this, this, and this, but all of them generally involve storing the original in another variable or wrapping it in an anonymous function (separate namespace).

Test code

var x = ' 0 '; // a global variable

document.body.innerHTML += x;
document.body.innerHTML += window.x;

// setTimeout before overriding
setTimeout(function () {
    document.body.innerHTML += ' 1 ';
}, 500);

// window.setTimeout before overriding
window.setTimeout(function() {
    document.body.innerHTML += ' 2 ';
}, 1000);

// Overriding setTimeout
function setTimeout(f, time) {
    'use strict';
    if (typeof f === 'function') {
        document.body.innerHTML += ' 3 ';
    }
}

// setTimeout after overriding
setTimeout(function () {
    document.body.innerHTML += ' 4 ';
}, 1000);

// window.setTimeout after overriding setTimeout globally
window.setTimeout(function () {
    document.body.innerHTML += ' 5 ';
}, 2000);

// Overriding window.setTimeout
window.setTimeout = function (f, time) {
    'use strict';
    if (typeof f === 'function') {
        document.body.style.backgroundColor = 'orange';
    }
};

// window.setTimeout after overriding
window.setTimeout(function () {
    document.body.innerHTML += ' 6 ';
}, 3000);

See jsFiddle. Note that after the fiddle initializes you may need to hit Run to see the delays.

Experimental result

0
undefined
3
3
(page becomes orange) 
2 (after a delay)
5 (after a longer delay)

Expected result

0
0
3
(page becomes orange)
1 (after 500ms)
2 (after 1000ms)
5 (after 2000ms)

Can anyone explain why my code's behaviour is different than expected?

Also, I realize that JavaScript run outside of a browser environment will differ, so for the purposes of this question I'll just stick to applications of JavaScript within a browser environment.

Community
  • 1
  • 1
rink.attendant.6
  • 44,500
  • 61
  • 101
  • 156
  • I'm famous! Haha I think that's cool that you actually took it out of the comments and made a question, instead of arguing it or just dismissing it – Ian Aug 09 '13 at 15:41

1 Answers1

0

Your code in JSFiddle does not run in the global scope. That is why window.x is undefined after declaring and defining x.

As for the local scope redefinition. You are allowed to do this:

var a;
a = b();
function b() {
    return 5;
}
console.log(a); // 5

You are allowed to call b before it's declared and defined because it's moved to the top. This is also known as hoisting.

Even if you do this:

function b () {
    return 1;
}
(function () {
    console.log(b()); // 2, not 1
    function b() {
        return 2;
    }
}());

Again, because of hoisting. The actual execution order is:

var b;
b = function () {
    return 1;
}
(function () {
    var b;
    b = function b() {
        return 2;
    }
    console.log(b()); // 2, makes sense
}());
Halcyon
  • 57,230
  • 10
  • 89
  • 128