Что такое использование имени или неназванного выражения класса в ES6?

В коде я использую названный класс "Автомобиль". Теперь, если я попытаюсь использовать как var carNew = new Car("ferrari");, то это вызовет мне ошибку. Итак, каково использование выражения named class в 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

Ответы

Ответ 1

В случае выражений класса вы можете использовать имя класса внутри, но не вне класса:

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"

Ответ 2

Со следующим кодом

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

var carNew = new Car("ferrari"); выдает ошибку, почему?

Car не ввел область действия, потому что вы написали выражение класса, аналогичное использованию function в выражении функции

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

var carNew = new Car("ferrari"); работает, почему?

По тем же соображениям, что и выше, идентификатор Car определен в вашей области действия и указывает на выражение класса


Что такое использование именованного или неназванного выражения класса [...]?

Давайте снова посмотрим на function. Итак, подумайте, если Bar не был определен в области, в которой мы работали, где она была определена?

Ну, очевидно, мы имеем foo.name === 'Bar', но мы могли бы также сделать

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

Отлично, поэтому мы можем ссылаться на Bar внутри функции.

Это точно то же самое с class, мы можем ссылаться на Car из самого выражения класса, позволяя нам делать рекурсивное поведение или копировать статические ссылки на экземпляры и т.д.

Я добавил такую ​​ссылку, чтобы ее было легко увидеть в коде ниже

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)

Ответ 3

То же самое, что и для названных/неименованных функций. Посмотрите на поведение функций:

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

Это очень похоже на ваш случай.

Где и зачем вам нужно его использовать? Обычно единственным вариантом использования функций является имя функций, называемых один раз, что дает вам возможность самодокументирования:

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

Здесь имя функции говорит, что ваша функция загружает ваше приложение.

Итак, я могу представить себе еще один случай для класса: вы можете использовать его для классов singleton, которые используются для создания только одного объекта

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

console.log(a.model);

Здесь вы просто называете класс, чтобы знать, что он делает, однако имя не будет доступно нигде.

Ответ 4

Он выкинул ошибку, потому что переменная Car не объявлена.

От JavaScript | MDN:

Важное различие между декларациями функций и классом объявления состоят в том, что объявления функций поднимаются и класс деклараций нет. Сначала вам нужно объявить свой класс, а затем обратитесь к нему, иначе код, подобный приведенному ниже, ReferenceError

Итак, чтобы использовать:

var newCar = Car('ferrari');

Вы должны определить переменную Car:

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

Обратите внимание, что мы используем Car, а не Car

Что касается неименованного и названного выражения класса, вот пример из JavaScript | Документация MDN:

Выражение класса - это еще один способ определить класс. Выражения класса могут быть названы или неназванными. Имя, присвоенное выражению named локально к телу класса.

// 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;
  }
};

Прочитайте классы ES6 - JavaScript | MDN для получения дополнительной информации

Ответ 5

Выражения класса

Аналогично функциям существуют два типа определений классов, два способа определения объявлений класса: class и выражения класса.

Аналогично функциям идентификатор выражения класса можно увидеть только внутри выражения:

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