03. Object Methods

Методы объекта -- это функции, определенные в качестве значения ключа объекта. Основным отличием метода объекта от обычной функции заключается в том, что в этом случае this внутри функции ссылается на сам объект.

Существует четыре вида синтаксиса для методов объекта:

  1. Функция-свойство

  2. Get/Set операции свойствах

  3. Метод объекта

  4. Стрелочная функция

const o = {
    functionProperty: function () { ... },
    get attributeProperty() { ... },
    set attributeProperty() { ... },
    methodProperty() { ... },
    arrowFunctionProperty: () => { ... }
}

Function-property

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

Для доступа к текущему объекту из свойства-функции используется ключевое слово this. Через this метод может не только обратиться к любому свойству объекта, но и передать куда-то ссылку на сам объект целиком. Значение this называется контекстом вызова и определяется каждый раз заново при каждом вызове функции. Если одну и ту же функцию запускать в контексте разных объектов, она будет получать разный this. Если извлечь функцию из объекта, она потеряет привязку к объекту и её this будет каким-то другим.

Get/Set access properties

Это специальная разновидность синтаксиса позволяет описать свойство объекта как комбинацию двух функций:

  • get prop()- функция вызывается на чтение свойства prop;

  • set prop()- функция вызывается на призвание свойства prop.

Когда программа пытается получить значение свойства с методами доступа, интерпретатор вызывает метод чтения (без аргументов). Возвращаемое этим методом значение становится значением выражения обращения к свойству. Когда программа пытается записать значение в свойство, интерпретатор вызывает метод записи, передавая ему значение, находящее справа от оператора присваивания. Этот метод отвечает за «установку» значения свойства. Значение, возвращаемое методом записи, игнорируется.

В отличие от свойств с данными, свойства с методами доступа не имеют атрибута writable. Если свойство имеет оба метода, чтения и записи, оно доступно для чтения/записи. Если свойство имеет только метод чтения, оно доступно только для чтения. А если свойство имеет только метод записи, оно доступно только для записи (такое невозможно для свойств с данными) и попытки прочитать значение такого свойства всегда будут возвращать undefined.

const name = "Anton";
const surname = "Kabysh";
const user = {
  name,
  surname,
  get fullName() {
    return `${name} ${surname}`;
  }
};

user.fullName; // Anton Kabysh

Основные свойства:

  • Если функции сеттера нет, то свойство изменить нельзя, даже делая эту операцию.

  • Если функции геттера нет, то свойство всегда будет возвращать undefined, хоть на попытку присваивания будет вызываться сеттер.

  • Технически, get/set функции свойств так же являются методами объекта.

  • Свойства с методами доступа наследуются так же, как обычные свойства с данными.

Shorthand object methods (ES6)

В ES6 добавлены методы объекта, которые, по сути, являются свойствами-функциями, привязанными к объекту. Их особенности:

  • Более короткий синтаксис объявления.

  • Наличие в методах специального внутреннего свойства [[HomeObject]] (“домашний объект”), ссылающегося на объект, которому метод принадлежит.

  • Доступно для обращения в методе ключевое слово super -- ссылка на объект прототипа.

const user = {
  name: "Anton",
  surname: "Kabysh",
  fullName() {
    return `${this.name} ${this.surname}`;
  }
};

user.fullName(); // Anton Kabysh

При создании метода — он привязан к своему объекту навсегда. Технически можно даже присвоить его в переменную и запустить отдельно, но super продолжат работать. На this данное правило не распространяется, что странно.

let parent = {
  x: "parent"
};
let child = {
  x: "child",
  papaX() {
    return super.x;
  }
};
child.papaX(); // undefined
Object.setPrototypeOf(child, parent);
child.papaX(); // 'parent'

Arrow Functions

Стрелочные функции характеризуются тем, что не обладают собственным this, а наследуют его из лексического контекста, где они находятся. Поэтому, this внутри стрелочной функции привязан не к объекту, а к тому this в области которого этот объект определен.

const global = this;
const c = {
  fn: () => this
};

c.fn() === global; // => true

Method Calls

There are two ways to call methods in JavaScript:

  • Dynamic dispatch (arr.slice(1)): property slice is searched for in the prototype chain of arr. Its result is called with this set to arr.

  • Direct call (Array.prototype.slice.call(arr, 1)): slice is called directly with this set to arr (the first argument of call()).

Прямой вызов функции позволяет вызвать код функции определенный в родителе на конкретном объекте this, если по каким-то причинам в наследниках код этой функции был переопределен. При прямом вызове функции объекта-прототипа можно рассматривать как глобальные статические функции, поскольку их поведение чисто и зависит только от this и аргументов.

Last updated