Skip to content
This repository has been archived by the owner on May 26, 2020. It is now read-only.

Latest commit

 

History

History
181 lines (134 loc) · 4.21 KB

File metadata and controls

181 lines (134 loc) · 4.21 KB

Новые возможности JavaScript — Классы

Классы в ECMAScript 6 — это синтаксический сахар, а не "честная" реализация, как в других языках. По сути, это те же конструкторы функций с использованием прототипов, только «приправленные» типичным синтаксисом в виде классов из ООП.
У классов, по сравнению с обычными функциями и переменными, есть особенности. Во-первых, классы не поднимаются (т.н. «hoisting») — поэтому обращаться к классу можно только после его декларации. Во-вторых, тело класса должно содержать только методы, но не свойства. Прототип, имеющий свойства, обычно считается анти-паттерном.
Также классы поддерживают геттеры и сеттеры в соответствии с объектными литералами.

// ECMAScript 5
function A(prop) {
  this.prop = prop;
}

A.prototype.setProp = function(prop) {
  this.prop = prop;
}

A.prototype.getProp = function() {
  return this.prop;
}

var a = new A('Example');

console.log(a.getProp());
// Ожидаемый результат: "Example"

a.setProp('Another example');

console.log(a.getProp());
// Ожидаемый результат: "Another example"
// ECMAScript 6
class A {
  constructor(prop) {
    this.prop = prop;
  }

  setProp(prop) {
    this.prop = prop;
  }

  getProp() {
    return this.prop;
  }
}

const a = new A('Example');

console.log(a.getProp());
// Ожидаемый результат: "Example"

a.setProp('Another Example');

console.log(a.getProp());
// Ожидаемый результат: "Another example"

// ECMAScript 5
function A() {
  // ...
}

function B() {
  // ...
}

A.prototype.prop = function() {
  return 1;
};

B.prototype.anotherProp = function() {
  return 2;
};

// Задаём наследование
B.prototype.__proto__ = A.prototype;

var b = new B();

console.log(b.prop());
// Ожидаемый результат: 1

console.log(b.anotherProp());
// Ожидаемый результат: 2

Однако стоит отметить, что доступ к ссылке __proto__ не доступен в Internet Explorer до 10 версии, и также является deprecated-способом для наследования. Для наследования в стандарте ES5 можно использовать метод Object.create.

// ECMAScript 5
function A() {
  // ...
}

function B() {
  // ...
}

A.prototype.prop = function () {
  return 1;
};

// Задаём наследование
B.prototype = Object.create(A.prototype);

B.prototype.anotherProp = function () {
  return 2;
};

var b = new B();

console.log(b.prop());
// Ожидаемый результат: 1

console.log(b.anotherProp());
// Ожидаемый результат: 2
// ECMAScript 6
class A {
  // ...

  prop() {
    return 1;
  }
}

class B extends A {
  // ...

  anotherProp() {
    return 2;
  }
}

const b = new B();

console.log(b.prop());
// Ожидаемый результат: 1

console.log(b.anotherProp());
// Ожидаемый результат: 2

В классе-наследнике нужно вызвать super() до того, как обращаться к свойствам через this, иначе произойдёт ошибка.

// ECMAScript 6
class A {
  // ...
}

class B extends A {
  constructor() {
  }
  
  // ...
}

const b = new B(); // Ошибка!

Также рекомендую прочитать статью «Новые #приватные поля классов в JavaScript» на Medium.