моя контактная информация
Почтамезофия@protonmail.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Класс в ES6 — это синтаксический сахар объектно-ориентированного программирования, предоставляющий краткий способ определения структуры и поведения объектов.
В языке JavaScript традиционный способ создания объектов экземпляра — через конструкторы. Ниже приведен пример.
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);
По сути, класс ES6 можно рассматривать как просто синтаксический сахар. Большинство его функций могут быть реализованы с помощью ES5. Новый метод написания класса только делает метод написания прототипа объекта более понятным и более похожим на синтаксис объектно-ориентированного программирования. Приведенный выше код переписан с использованием классов ES6 следующим образом:
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
Классы ES6 можно рассматривать как еще один способ написания конструкторов:
class Point {
// ...
}
typeof Point // "function"
Point === Point.prototype.constructor // true
----------------------------------------------------------------------------
class Point {
constructor() {
// ...
}
toString() {
// ...
}
toValue() {
// ...
}
}
// 等同于
Point.prototype = {
constructor() {},
toString() {},
toValue() {},
};
1. Декларативный синтаксис: используйте ключевое слово class, чтобы объявить класс.
2. Конструктор: используйте метод конструктора для инициализации экземпляра класса.
3. Методы экземпляра: общий метод, определенный внутри класса. Используйте его для доступа к свойствам экземпляра.
4. Статические методы: определяется с использованием ключевого слова static и не зависит от экземпляра класса.
5. Свойства экземпляра: Инициализируйте в конструкторе или используйте синтаксис объявления полей (в настоящее время это предложение на этапе 3).
6. Наследование: реализовано с использованием ключевого слова Extensions.
7. суперключевое слово: вызов конструктора или метода родительского класса в конструкторе подкласса.
8. геттер и сеттер: используйте get и set для определения средств доступа к свойствам.
9. Частные свойства и методы: используйте # для определения частных свойств и методов (в настоящее время это предложение на этапе 3).
1. Определение базового класса и создание его экземпляров
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return `Point(${this.x}, ${this.y})`;
}
}
let point = new Point(10, 20);
console.log(point.toString()); // 输出: Point(10, 20)
2. Статические методы и свойства
class MathUtils {
constructor() {
console.log(MyClass.myStaticProp); // 42
}
static add(a, b) {
return a + b;
}
static myStaticProp = 42;
}
console.log(MathUtils.add(1, 2)); // 输出: 3
3. Наследование и супер
class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}
area() {
return this.width * this.height;
}
}
class Square extends Rectangle {
constructor(sideLength) {
super(sideLength, sideLength);
}
}
let square = new Square(5);
console.log(square.area()); // 输出: 25
4. геттер и сеттер
class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}
get area() {
return this.width * this.height;
}
set width(newWidth) {
if (newWidth > 0) {
this.width = newWidth;
} else {
console.log("Width must be positive.");
}
}
}
let rect = new Rectangle(4, 5);
console.log(rect.area); // 输出: 20
rect.width = -10; // 输出: Width must be positive.
(1) Строгий режим
Внутри классы и модули по умолчанию находятся в строгом режиме, поэтому нет необходимости использовать use strict для указания режима работы. Пока ваш код написан в классе или модуле, доступен только строгий режим. Учитывая, что весь будущий код фактически будет выполняться в модулях, ES6 фактически переводит весь язык в строгий режим.
(2) Нет продвижения
В классах нет переменного подъема (hoist), что полностью отличается от ES5.
new Foo(); // ReferenceError
class Foo {}
//不会报错
//因为 Bar 继承 Foo 的时候, Foo 已经有定义了。
//但是,如果存在 class 的提升,上面代码就会报错,
//因为 class 会被提升到代码头部,而 let 命令是不提升的,
//所以导致 Bar 继承 Foo 的时候, Foo 还没有定义。
{
let Foo = class {};
class Bar extends Foo {
}
}
(3) атрибут имени
Поскольку по сути класс ES6 — это всего лишь оболочка конструктора ES5, многие возможности функции наследуются классом, включая атрибут name.
class Point {}
Point.name // "Point"
//name 属性总是返回紧跟在 class 关键字后面的类名。
(4) Метод генератора
Если перед методом стоит звездочка (*), это означает, что метод является функцией-генератором.
class Foo {
constructor(...args) {
this.args = args;
}
* [Symbol.iterator]() {
for (let arg of this.args) {
yield arg;
}
}
}
for (let x of new Foo('hello', 'world')) {
console.log(x);
}
// hello
// world
//Foo 类的 Symbol.iterator 方法前有一个星号,表示该方法是一个 Generator 函数。
//Symbol.iterator 方法返回一个 Foo 类的默认遍历器, for...of 循环会自动调用这个遍历器。
(5) Суть этого
Если метод класса содержит это, он по умолчанию указывает на экземпляр класса. Однако вы должны быть очень осторожны, так как этот метод может вызвать ошибки, если использовать его отдельно.
class Logger {
printName(name = 'there') {
this.print(`Hello ${name}`);
}
print(text) {
console.log(text);
}
}
const logger = new Logger();
const { printName } = logger;
printName(); // TypeError: Cannot read property 'print' of undefined
Избегайте использования этого, свяжите это в конструкторе:
class Logger {
constructor() {
this.printName = this.printName.bind(this);
}
// ...
}
Избегайте использования этого, используйте функции стрелок:
class Obj {
constructor() {
this.getThis = () => this;
}
}
const myObj = new Obj();
myObj.getThis() === myObj // true
Не используйте это, используйте прокси
function selfish (target) {
const cache = new WeakMap();
const handler = {
get (target, key) {
const value = Reflect.get(target, key);
if (typeof value !== 'function') {
return value;
}
if (!cache.has(value)) {
cache.set(value, value.bind(target));
}
return cache.get(value);
}
};
const proxy = new Proxy(target, handler);
return proxy;
}
const logger = selfish(new Logger());