1

When I use the ES6 class syntax, a variable inside a method declared without 'let' or 'var' is undefined. However, when using the regular object syntax, it is defined.

To illustrate the problem, I run the following code on Node v7.5.0:

class ES6Foo {

   bar() {  

       var i = 5446;
       console.log("i = " + i);

       let j = 5446;
       console.log("j = " + j);

       k = 5446;
       console.log("k = " + k);

    }
}

foo = new ES6Foo();
foo.bar();

produces the output:

i = 5446
j = 5446
.../ES6Foo.js:10
    k = 5446;
      ^
ReferenceError: k is not defined
at ES6Foo.bar 

Not using the class syntax solves this problem:

var OldFoo = function() {}

OldFoo.prototype.bar = function() {

   var i = 5446;
   console.log("i = " + i);

   let j = 5446;
   console.log("j = " + j);

   k = 5446;
   console.log("k = " + k);

}

foo = new OldFoo();
foo.bar();

produces:

i = 5446
j = 5446
k = 5446

Can anyone explain this behavior?

  • 4
    The code in a `class` is executed using strict mode. This forbids implicit globals. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#Strict_mode –  Feb 08 '17 at 17:30
  • 2
    I'd argue that your second code example doesn't solve a problem, but rather allows a problem. –  Feb 08 '17 at 17:32

1 Answers1

6

When I use the ES6 class syntax, a variable inside a method declared without 'let' or 'var' is undefined.

Actually, it's undeclared. That's why you get an exception.

However, when using the regular object syntax, it is defined.

That's because ES6 class methods automatically run in strict mode, your regular object syntax does only run in sloppy mode. (It should not! "use strict" mode everywhere!)
Assigning to an undeclared identifier will implicitly create a global variable, a thing which you'll definitely want to avoid.

Not using the class syntax solves this problem

No, the problem is solved by properly declaring the variable.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thanks! Is it a good rule of thumb to always declare variables with a keyword, even though you can get away with it outside of strict mode? Is there ever a situation where you would want to implicitly create a global variable? – Brian Zanti Feb 08 '17 at 18:17
  • 3
    @BrianZanti *"Is there ever a situation where you would want to implicitly create a global variable?"* – No. Such implicit behaviour is a terrible trap to consciously leave in your code base. Pretty much every linter will warn of their existence, and I would immediately reject the offensive lines in code review. – Mulan Feb 08 '17 at 18:38