Есть некоторые отличия между классом и функцией - большинство людей начнет с того, что класс «просто синтаксический сахар», но этот сахар имеет значение совсем немного. Когда анализатор JS является prosessing код JavaScript анализатор будет сохранять их в различных узлах AST, как показано здесь ClassDeclaration и ClassExpression различные типы узлов в дереве resultin AST:
https://github.com/estree/estree/blob/master/es6.md#classes
You можно видеть, что для этого анализатора, новый ES6 Классы спецификации вводит ряд новых AST элементов в синтаксисе:
- ClassBody
- MethodDefinition
- ClassDeclaration
- ClassExpression
- MetaProperty
Поскольку синтаксис AST не является стандартным, может быть больше или меньше типов в зависимости от синтаксического анализатора, но важно отметить, что, когда код входит в объявление класса или выражение класса, которое будет интерпретироваться по-разному механизмом JavaScript.
Это означает, что объявления класса и функции не могут быть обменены. Вы можете увидеть это, если вы пытаетесь написать
class notWorking {
return 1; // <-- creates a parser error
};
Это потому, что когда анализатор встречает класс -ключевое слово, он начнет обрабатывать следующий код как ClassBody либо ClassDeclaration или ClassExpression, а затем он expexts найти MethodDefinitions.
Это небольшая проблема, потому что создание частных переменных становится немного сложнее.Объявление функции можно определить приватную переменную аккуратно, как это:
function myClass() {
var privateVar;
}
Объявление класса не может иметь это:
class myClass {
var privateVar; // ERROR: should be a method
}
Это происходит потому, что синтаксис класса позволяет только методы должны быть объявлены внутри класса тело. По крайней мере сейчас.
Однако, существует предложение о создании частных полей:
https://github.com/zenparsing/es-private-fields
Таким образом, в будущем вы могли бы сказать
class myClass {
#privateVar; // maybe this works in the future?
}
Существует отдельный ответ с учетом частного свойства в классах ES6, что предполагает некоторые обходные пути, такие как использование символов:
Private properties in JavaScript ES6 classes
var property = Symbol(); // private property workaround example
class Something {
constructor(){
this[property] = "test";
}
}
Естественно, существуют различия между классами и функциями. Один из них подъемное1 - в отличие от функций, вы не можете объявить класс в любом месте в области видимости:
Важное различие между декларациями функций и класса деклараций, что функция деклараций водрузили и класс декларации не. Сначала вам нужно объявить свой класс, а затем получить к нему доступ
Декларации классов и декларации функций очень похожи;
function foo1() {} // can be used before declaration
class foo2{} // new foo2(); works only after this declaration
Класс выражения работают совершенно аналогично функционировать exressions, например, они могут быть отнесены к переменной:
var myClass = class foobar {};
Другие отличия 1
- Класс exression/декларация тела всегда выполняется в Строгий режим - не нужно указывать, что вручную
- У классов есть специальное ключевое слово конструктор - может быть только один из них, или возникает ошибка. Функции могут иметь несколько определений переменной функции с именем «конструктор»
- Классы имеют специальное ключевое слово super, которое относится к конструктору родительских классов. Если вы находитесь внутри конструктора, вы можете вызвать super (x, y);, чтобы вызвать конструктор родительского класса, но внутри метода вы можете вызвать super.foobar(), чтобы создать вызов любой функции родительского класса. Такая функциональность недоступна для стандартных функций, хотя вы можете подражать ей с помощью некоторых пользовательских хакеров.
- Внутри класса тела вы можете определить функцию с статическим ключевым словом, поэтому его можно вызывать только с использованием ClassName.FunctionName() -syntax.
- Оба объявления классов и выражения можно использовать расширяет ключевое слово как класс Dog расширяет ANIMAL
- MethodDeclaration не нуждается в функции -prefix, таким образом, вы можете определить функцию «ОК» внутри класса «м», как это: класс m {ok() {}}. На самом деле это даже не позволили определить функцию класса т {функции ок() {}}
Однако, после того, как синтаксический анализатор закончил его работу, экземпляр класса, по существу, работает точно так же, как и любой другой объект.
Новый синтаксис класса ES6 - это, по существу, более четкий способ выражения объектов традиционным способом ООП, и если вам это нравится, вы должны его использовать.
EDIT: Кроме того, синтаксис класса ES6 имеет и другое ограничение: он не позволяет использовать функции-члены с помощью лексической привязки с использованием стрелки жира. Кажется, что ES7 имеет experimental feature, что позволяет. Это может быть полезно, например, при связывании методов с обработчиками событий, связанный с ним вопрос - here.
1https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
Это как, 'переменная х = (то)? 1: 0' выгоды от 'var x; if (someThing) {x = 1; } else {x = 0; } 'Может быть читабельнее. –
Этот ответ (хотя и не является точным дубликатом) объясняет различия очень хорошо: http://stackoverflow.com/questions/30783217/why-should-i-use-es6-classes – CodingIntrigue
Что не так с stackoverflow, -5 для просто спрашивать обычный вопрос. Я думаю, этого достаточно, узнал бы сам. Спасибо за респондентов, которые пытались дать объяснение, я ценю это. –