Что такое использование имени или неназванного выражения класса в 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