13

Why is the following html file showing title as default in IE? The other browsers show title as mytitle.

<script>
window.mylib = window.mylib || {};
mylib.title = 'mytitle';
</script>

<script>
var mylib = mylib || {};
document.title = mylib.title || 'default';
</script>

Does IE create a separate scope for each of the script tags?

And is that just a bug or why does the behavior differ?

(tested in IE8 and latest chrome/ff/opera)

Martin Hansen
  • 5,154
  • 3
  • 32
  • 53
  • Might be a hoisting bug. I imagine `var mylib = window.mylib || {};` makes your second script work as expected? – Frédéric Hamidi Aug 12 '13 at 12:49
  • Actually not, I thought it would though. – Martin Hansen Aug 12 '13 at 12:51
  • Might not be a bug but rather a difference in the spec. IE8 is an ECMAScript 3 browser while IE9+, Chrome, etc. are ES5 browsers. Couldn't say what of ES3 would cause that, though. – Jonathan Lonowski Aug 12 '13 at 12:51
  • @Martin, there is a good way to be sure. If you rename `var mylib` to `var _mylib` in the second snippet, does the code work? If that's the case, it looks like redefining `mylib` in the global scope (through `var`) overwrites the existing `window.mylib`. – Frédéric Hamidi Aug 12 '13 at 12:54
  • couldn't it really be that `var mylib` doesn't get hoisted up to the very top but only to the top of the script tag. That would result in `mylib` being redefined as `undefined` in the second tag. You could try to omit the `var` and check what happens then. – basilikum Aug 12 '13 at 13:01
  • @basilikum yes that's what we're seeing. And hoisting only happens AFAIK inside a new scope right? It does work with removing the var. Or use window.mylib in both places. But I'm not really after how to fix it. I just wonder why is it like this. – Martin Hansen Aug 12 '13 at 13:07

3 Answers3

3

HTML <script> tags Javascript are executed in the scope of the window. Thus, separated script tags are executed on the same scope.

Specifically with IE7, try not re-defining the variable on the second time:

Instead of

var mylib = mylib || {};

use

mylib = window.mylib || {};

IE7 probably overwrites the definition of mylib when var mylib is encountered.

EZLearner
  • 1,614
  • 16
  • 25
3

Scope shouldn't be an issue. Each <script> should be evaluated within the same global scope.

However, window.mylib = ... doesn't appear to be considered an actual declaration in IE8. So, following it with a var mylib causes an override / reset to undefined.

<script>
  window.mylib = {};
</script>

<script>
  console.log(typeof window.mylib); // object
</script>

<script>
  var mylib;
  console.log(typeof window.mylib); // undefined
</script>

It should work as expected when using either var mylib or window.mylib throughout. Seems it's just the mixture that's the problem.

<script>
  var mylib = mylib || {};
  mylib.title = 'mytitle';
</script>

<script>
  var mylib = mylib || {};
  document.title = mylib.title || 'default'; // 'mytitle'
</script>
Jonathan Lonowski
  • 121,453
  • 34
  • 200
  • 199
0

You are initializing window.mylib in the first <script> tag. In the second <script> tag you are initializing var mylib with mylib not window.mylib. And then checking the value of title against this. There seems some logic issues if I am able to understand it correctly.

The <script>s are scoped to the window so it does not matter how many you have and in which one you are accessing the variables or functions as long as they are properly defined and/or initialized.

Vivek Jain
  • 3,811
  • 6
  • 30
  • 47