16

In the code I am using a named class "Car". Now if I try to use like var carNew = new Car("ferrari");, then it's throwing me an error. So what is the use of named class expression in ES6?

'use strict';
var car = class Car{
  constructor(model){
        this.model = model;
    }
}
var carNew = new car("ferrari");

console.log(carNew); //car {model: "ferrari"}
console.log(carNew.constructor == car); //true
Cœur
  • 37,241
  • 25
  • 195
  • 267
  • What error is thrown? – Amit Jan 02 '16 at 11:30
  • Uncaught ReferenceError: Car is not defined – nihar jyoti sarma Jan 02 '16 at 11:31
  • above code will not throw an error if used the class name as "Car",then only it will throw the error.I want to understand what is the use of named and unamed class expression?when we need to use the named class expression – nihar jyoti sarma Jan 02 '16 at 11:42
  • `class` wraps the constructor function, so you can't just call the class like it was a constructor function; as a side note [you could use the instance's contructor](https://jsfiddle.net/maio/zhojxn51/1/) – maioman Jan 02 '16 at 11:48
  • 1
    Closely related: [Why use named function expressions?](http://stackoverflow.com/q/15336347/1048572) – Bergi Jan 02 '16 at 16:58

5 Answers5

10

In case of class expressions you can use class name internally, but not outside of the class:

const Foo = class Self {
  static greetingPrefix() {
    return 'Hello, ';
  }

  greeting() {
    return Self.greetingPrefix() + 'World';
  }
};

const foo = new Foo();
console.log(foo.greeting()); // "Hello, World"


console.log(Self); // throws "Uncaught ReferenceError: Self is not defined"
alexpods
  • 47,475
  • 10
  • 100
  • 94
  • Please note that static class properties are not part of the ES 6 spec, they are proposed for ES 2016 (aka ES 7). – Jared Smith Jan 02 '16 at 15:21
  • 5
    @JaredSmith Yes, class **properties** are not part of the ES6. But class **methods** (which are used in the example) are part of the spec (see [here](http://www.ecma-international.org/ecma-262/6.0/#sec-14.5)) – alexpods Jan 02 '16 at 15:34
8

With the following code

var car = class Car{ /* ... */ }

var carNew = new Car("ferrari"); throws an error, why?

Car has not entered the scope because you've written a class expression, similar to using function in a function expression

var foo = function Bar() {};
foo; // defined
Bar; // undefined

var carNew = new car("ferrari"); works, why?

For the same reasoning as above, the car identifier is defined in your scope and points to the class expression


What is use of named or unnamed class expression [...]?

Lets look back at function again. So now think, if Bar wasn't defined in the scope we were working in, where was it defined?

Well, obviously we have foo.name === 'Bar', but we could also do

var foo = function Bar() {console.log(Bar)};
foo(); // Bar logged, we see Bar === foo here

Great, so we can reference Bar inside the function.

It is exactly the same with class, we can reference Car from within the class expression itself, letting us do recursive behaviours or copy static references to instances etc.

I've added such a reference to make it easy to see in the code below

var car = class Car {
    constructor(model) {
        this.model = model;
        this.foo = Car; // the big C Car that was ReferenceErroring outside
    }
};
var bar = new car();
console.log(bar.foo); // logs class Car (=== car)
Paul S.
  • 64,864
  • 9
  • 122
  • 138
2

The same use as of named / not named functions. Look at the functions behavior:

var a = function b() { console.log('b') }
>> undefined
a()
>> b
b()
>> Uncaught ReferenceError: b is not defined(…)

This is very similar to your case.

Where and why you would need to use it? Usually the only use case for functions is to name the functions called once which gives you kind of self-documenting ability:

(function bootstrap() {
  //
})();

Here the function name says that your function bootstraps your app.

So I can imagine another case for the class now: you can use it for singleton classes which are used to create one object only:

var a = new (class Car{
  constructor(model){
        this.model = model;
    }
})('ferrari');

console.log(a.model);

Here you just name the class to know what it is doing, however the name won't be accessible elsewhere.

smnbbrv
  • 23,502
  • 9
  • 78
  • 109
1

It thrown an error because Car variable is not declared.

From JavaScript | MDN documentation :

An important difference between function declarations and class declarations is that function declarations are hoisted and class declarations are not. You first need to declare your class and then access it, otherwise code like the following will throw a ReferenceError

So, to use :

var newCar = Car('ferrari');

You have to define the Car variable :

var Car = class Car{
  constructor(model){
        this.model = model;
    }
}

Notice here that we use Car and not car

Concerning unamed and named class expression, here is an example from JavaScript | MDN documentation :

A class expression is another way to define a class. Class expressions can be named or unnamed. The name given to a named class expression is local to the class's body.

// unnamed
var Polygon = class {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};

// named
var Polygon = class Polygon {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};

Read ES6 classes - JavaScript | MDN for more information

Louis Barranqueiro
  • 10,058
  • 6
  • 42
  • 52
1

Class expressions

Similarly to functions, there are two kinds of class definitions, two ways to define a class: class declarations and class expressions.

Also similarly to functions, the identifier of a class expression is only visible within the expression:

const MyClass = class Me {
    getClassName() {
        return Me.name;
    }
};
const inst = new MyClass();
console.log(inst.getClassName()); // Me
console.log(Me.name); // ReferenceError: Me is not defined
arcseldon
  • 35,523
  • 17
  • 121
  • 125