8

If I have

Class Car {}

do I need to wrap that with our function closure? Do var's get hoisted to window? or just to the class? What about when transpiled? Does Traceur/babel turn it into a IIFE and let's into var's?

Do I need to:

(function(){ 
    Class Car() {}
}());

To be safe?

Travis J
  • 81,153
  • 41
  • 202
  • 273
webdevinci
  • 310
  • 3
  • 10
  • 1
    That would depend on if you are loading the file as a script, or as a module. How are you loading the file? – loganfsmyth Oct 06 '15 at 20:43
  • Natively, it's a really good question. Tested here with Edge, and although I can have a `car.js` file with that class declaration, and a `new-car.js` file using that class, if I log `Car` into the console, it shows me the constructor, but if I log `window.Car`, it shows `undefined`. – Buzinas Oct 06 '15 at 20:48
  • @Buzinas: That's a bit different. Lexical declarations (`class`, `let` and `const`) do not become properties of the global object. – Felix Kling Oct 07 '15 at 01:25
  • @Buzinas & Felix Kling, Both very good points and considerations, thanks for the heads up – webdevinci Oct 08 '15 at 11:07

3 Answers3

4

There does not need to be an IIFE wrapper for the class car as shown here, in fact that will create an execution context and hide the class from the rest of the page.

So you would just leave it as (not the lower case)

class Car(){}

Var is still hoisted in the same manner it was before. It will get hoisted to the top of the execution context. If the code is currently in the window's context, that is where the var will end up.

Classes are not hoisted in ECMAScript 6. So the class will be available only after it has been declared.

Travis J
  • 81,153
  • 41
  • 202
  • 273
  • Classes do get hoisted, meaning the *binding* is created when entering the scope, but it is not initialized. It behaves like `let`. – Felix Kling Oct 07 '15 at 01:24
  • @FelixKling - That is what it says at MDN. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes "An important difference between function declarations and class declarations is that function declarations are hoisted and class declarations are not." Did I interpret it incorrectly? It seems rather direct. – Travis J Oct 07 '15 at 04:25
  • Mmh, I was referring to what is written in http://www.ecma-international.org/ecma-262/6.0/#sec-functiondeclarationinstantiation, step 35. But I guess "hoisting" has a different meaning than I thought (maybe?). classes and `let` declarations are definitely not considered to be HoistableDeclaration in the spec, so I guess I was wrong. However, even the spec doesn't seem to describe the term "hoisting" explicitly. – Felix Kling Oct 07 '15 at 04:40
  • @FelixKling - It was a little confusing to me. I looked at what the class gets transpiled into, and it just seems like an IIFE with a returned instantion similar to jQuery. But the returned value would have to be hoisted somewhere I thought. I am not sure, and do not have anything to actually test with for es6 in order to verify. – Travis J Oct 07 '15 at 16:57
  • I suppose I was a bit ambiguous and asking 2 questions. One with ECMAScript 6, how it works, and then how babel works with transpiling (aka does attach the class to window object). Side note: Along the way in researching I found 'let' does not hoist like vars do, they are declared where they are declared.... interesting. Thanks for help guys – webdevinci Oct 08 '15 at 11:11
2

You can have a look at what happens when Babel transpiles your code here

You don't need to use an IIFE unless you want to hide the class, and the var Class that gets generated is hoisted as any variable: the declaration will take place at the start, but the assignement will take place in the original line.

And yes, Babel turns let into var, but it also takes care scoping works as expected with extra asignements. If you just want to write ES6 code and execute it you shouldn't have to worry about these details, just follow the ES6 (ES2015) standard.

Arcadio Garcia
  • 499
  • 1
  • 4
  • 16
1

No, there's no need to wrap it like that as long as it's in code being treated as an ES6 module. Babel's default settings treat input code and files as modules. Babel does introduce functions in various places to implement correct scoping semantics, and does transform let into var if you have the applicable transformer enabled.

ES6 modules are always in strict mode and here's what the spec says about assignment in strict mode:

Assignment to an undeclared identifier or otherwise unresolvable reference does not create a property in the global object. When a simple assignment occurs within strict mode code, its LeftHandSide must not evaluate to an unresolvable Reference.

http://www.ecma-international.org/ecma-262/6.0/#sec-strict-mode-of-ecmascript

What exactly do you mean by?:

Do var's get hoisted to [...] the class?

JMM
  • 26,019
  • 3
  • 50
  • 55