0

Javascript "classes" declared with the class keyword don't seem to appear in the window object. I'm trying to find a class object by name, e.g. window['A'].

<html><head><script type='text/javascript'>
    function A() {}
    console.log(A) // outputs function A
    console.log(window.A) // same
    console.log(window['A']) // same

    class B {}
    console.log(B) // outputs class/function B
    console.log(window.B) // undefined
    console.log(window['B']) // undefined
</script></head></html>

I'm getting this behavior both in Chrome 52.0.2743.116 and Firefox Developer 50.0a2 (2016-08-27).

Looking at the MDN article on the class keyword, it mentions that such declarations aren't "hoisted" like function declarations, but that seems to be a different issue. I've looked through the specs but as far as I can tell this should behave like a function. ("7. Let env be the running execution context’s LexicalEnvironment. 8. Let status be InitializeBoundName(className, value, env)." seem to be the relevant points)

Does anyone know if this is a bug or I've missed something and this is by design? If so, is there another way of getting a class by it's declared name?

Adrian Leonhard
  • 7,040
  • 2
  • 24
  • 38
  • did you try `window.B = class {};` ? Besides, isn't it a good thing that it doesn't assume what scope you're in and doesn't accidentally corrupt B of global scope unless you explicitly tell it to? But yeah it's a strange inconsistancy, where is class stored if it's not in global scope, as there is no closure around the code, so it should default to window. – Dmytro Aug 27 '16 at 17:30
  • 2
    Maybe also of interest: [Javascript ES6 class definition not accessible in window global](http://stackoverflow.com/questions/37711603) – t.niese Aug 27 '16 at 17:32
  • @t.niese Thanks, looks like I fail at googling. I'll take a look at those now and probably close the question. – Adrian Leonhard Aug 27 '16 at 17:40
  • @Dmitry I would say it the other way round. I think with `"use strict"` they should also have changed the behaviour of `var` and `function` to be not placed in `window`, because it was always a strange and problematic thing that both `var`/`function` and elements having an `id` will all result in being placed in window. But I guess to not break current code and to keep backwards compatibility with older browsers not supporting `"use strict"` they only changed the behaviour for the new keywords. – t.niese Aug 27 '16 at 17:48
  • @Dmitry I'm also relying on the class name itself, so it looks like I'll have to do `B = class B {}`, which is kind of ugly. Not adding them to the global scope would be fine if there were something akin to Java's `Class.forName`. – Adrian Leonhard Aug 27 '16 at 18:00
  • You probably might want to write your code according to modules using `export class B {}`. The problem is that this is not support by browsers right now, so you need to transpile it according to your module loader. – t.niese Aug 27 '16 at 18:19
  • @AdrianLeonhard it's not ugly at all, why do you think it's ugly? It's far uglier to rely on the scope to be window. What if it's run from nodejs and has no window, but has global? What if it's being run from a "new" scope. by explicitly setting the scope to window you make your intent explicit, and throws an exception early if there is no window object. All my code is always wrapped in closures so I never rely on "this" to be window. Relying mutating "current scope whatever it is" is fairly clumsy coding habit, as it causes subtle bugs hard to track. – Dmytro Aug 27 '16 at 19:11

0 Answers0