Logo
Книга для начинающих
ВходРегистрация
/
Программирование
/
Курс JavaScript
/

Объекты

JavaScript: Объекты

JavaScript поддерживает объектно-ориентированное программирование (ООП) — это, очень упрощённо, подход, при котором мы оперируем не данными и функциями, а объектами и методами. Мы не планируем подробно останавливаться на этом в данном курсе, потому что тема объёмная и для понимания требует определённого уровня подготовки. Совсем игнорировать её невозможно, потому что объекты появляются буквально сразу, как только мы начинаем писать код на JavaScript. Поэтому мы коснёмся этой темы, но только на том уровне, на котором это нужно для текущих задач.

До этого момента мы работали с данными и применяли к ним функции. В ООП у нас вместо данных объекты, на которых вызываются методы. Например, строки в JavaScript являются объектами, и у них есть метод toUpperCase(), который переводит все буквы в верхний регистр.

const name = 'Robb';
console.log(name.toUpperCase()); // => ROBB

В отличие от функций, методы вызываются на объекте. Сначала записывается объект (значение, переменная или константа), затем, через точку, вызов метода. Несмотря на то что метод toUpperCase() не принимает аргументов, он внутри себя знает, на каком объекте вызывается, и у него есть доступ к самому объекту.

Свойства

Кроме методов, у данных есть свойства. Свойство — это связанное с данными значение, к которому обращаются через точку сразу после переменной или константы. Например, у строк есть длина — свойство length:

const name = 'Robb';
const len = name.length;
console.log(len); // => 4

В предыдущих модулях для получения длины строки мы использовали учебную функцию length() из библиотеки hexlet-basics/string:

import { length } from 'hexlet-basics/string';

const name = 'Robb';
console.log(length(name)); // => 4

Это была временная замена — во многих языках длина строки действительно вычисляется через специальную функцию. В JavaScript же длина встроена прямо в язык как свойство .length. Начиная с этого урока учебная функция больше не понадобится: везде используем .length.

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

JavaScript позволяет обращаться к свойствам, которые не существуют (например, при опечатках). В таком случае их значением является undefined:

const name = 'Robb';
console.log(name.whatIsThat); // => undefined

Вопрос для самопроверки. Что распечатает код console.log(name[name.length]) для name, определённого выше? Почему ответ такой?

Ответ

Код распечатает undefined, потому что происходит обращение по индексу, который выходит за границу строки. В этом случае name.length — 4, а индекс последнего символа в строке — 3.

Методы строк

Методов у данных обычно значительно больше, чем свойств. У строк их несколько десятков, вот некоторые из них.

// Перевод всех букв в верхний регистр
console.log('hexlet'.toUpperCase()); // => HEXLET

// Перевод всех букв в нижний регистр
console.log('HeXleT'.toLowerCase()); // => hexlet

// Удаление пробелов в начале и конце строки
console.log('   hi   '.trim()); // => hi

Некоторые методы принимают параметры. Например, у метода replace() первый параметр содержит подстроку, которую нужно заменить, а второй — строку-замену.

const text = 'abracadabra';

// Заменяется только первое вхождение
console.log(text.replace('a', 'o'));    // => obracadabra
console.log(text.replace('abra', '!')); // => !cadabra

Методов в JavaScript действительно много, и их не учат наизусть. Обычно программисты в процессе работы запоминают, какие операции им вообще нужны и как примерно называются такие методы. При возникновении задачи они либо вспоминают подходящий метод, либо быстро находят его в документации.

Методы есть и у чисел

const temperature = 22.93;
// Округление до одного знака после запятой
const roundedTemperature = temperature.toFixed(1);
// Метод возвращает строку, которая содержит преобразованное число
console.log(roundedTemperature); // => 22.9

// Напрямую можно вызывать так
// Скобки нужны обязательно, иначе не заработает
(22.93).toFixed(1); // 22.9

Хозяйке на заметку. Технически всё несколько сложнее. Методы есть не у самих чисел, а у данных (объектов) типа Number. Числа, записанные в переменные или константы, автоматически преобразуются к данному типу во время обращения к ним — в это время происходит так называемый boxing.

Метод и функция: сравнение

С точки зрения кода методы и функции ведут себя похоже. Они принимают значения и возвращают результат. Отличаются только синтаксисом вызова.

// Вызов функции
Math.min(3, 5);

// Вызов метода
'hexlet'.toUpperCase();

Функция вызывается снаружи и получает аргументы в скобках. Метод представляет собой операцию, встроенную в само значение. Под капотом значение передаётся внутрь, но это скрыто от нас.

Возникает закономерный вопрос: зачем нужны методы, почему не просто функции? Есть две причины, почему так сложилось:

  1. Исторически так получилось. JavaScript разрабатывался слишком быстро, поэтому не всё было продумано хорошо.
  2. Далеко не все функции имеют отношение к конкретному значению. Возьмём для примера Math.min() — она находит минимальное среди переданных чисел. Делать её методом конкретного числа, например (1).min(), нелогично: она не связана с одним конкретным числом.

С другой стороны, функции, работающие с конкретным значением, для единообразия логично реализовывать как методы. JavaScript — язык, в котором прижились оба подхода: в нём активно используются как обычные функции, так и методы. Подробнее о плюсах и минусах этих подходов рассказывается в курсах, посвящённых ООП.

Методы возвращают значения

Как и функции, методы возвращают результат. Их можно использовать в составе выражений.

const name = 'hexlet';
console.log(name.toUpperCase() + '!'); // => HEXLET!

Методы строк всегда возвращают новую строку, оставляя исходную без изменений. Это поведение называется иммутабельностью. Мы ещё поговорим об этом в следующем уроке, но пока важно понимать, что строка остаётся прежней, а результат метода является новым значением.

const name = 'hexlet';
console.log(name.toUpperCase()); // => HEXLET
console.log(name);               // => hexlet

Свойства и методы в выражениях

Свойства и методы — такие же выражения, как переменные, константы или вызовы функций. Их можно использовать в арифметических операциях и передавать как аргументы другим функциям.

Использование в операциях:

const name = 'Shaya';
console.log(name.length + 5);          // => 10
console.log(`hi, ${name.toUpperCase()}!`); // => hi, SHAYA!

Использование как аргументов функций:

const firstName = 'Robb';
const lastName = 'Shaya';
// Передаём свойства прямо в вызов функции
console.log(Math.min(firstName.length, lastName.length)); // => 4

Это позволяет писать компактный и выразительный код, не сохраняя промежуточные результаты в отдельных переменных.

Задание

Пользователь ввёл текст с включённым caps lock — буквы в разном регистре. Перед сохранением программа приводит текст к нижнему регистру. Приведите строку из переменной text к нижнему регистру и выведите на экран. Пример метода, выполняющего эту задачу, приведён в теории.

Коммерческий опыт и Трудоустройство

Полезное

  • Методы строки

Команда проекта находится в телеграм-сообществе. Там можно задать любой вопрос и повлиять на проект

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются
/
Программирование
/
Курс JavaScript
/

Объекты

JavaScript: Объекты

JavaScript поддерживает объектно-ориентированное программирование (ООП) — это, очень упрощённо, подход, при котором мы оперируем не данными и функциями, а объектами и методами. Мы не планируем подробно останавливаться на этом в данном курсе, потому что тема объёмная и для понимания требует определённого уровня подготовки. Совсем игнорировать её невозможно, потому что объекты появляются буквально сразу, как только мы начинаем писать код на JavaScript. Поэтому мы коснёмся этой темы, но только на том уровне, на котором это нужно для текущих задач.

До этого момента мы работали с данными и применяли к ним функции. В ООП у нас вместо данных объекты, на которых вызываются методы. Например, строки в JavaScript являются объектами, и у них есть метод toUpperCase(), который переводит все буквы в верхний регистр.

const name = 'Robb';
console.log(name.toUpperCase()); // => ROBB

В отличие от функций, методы вызываются на объекте. Сначала записывается объект (значение, переменная или константа), затем, через точку, вызов метода. Несмотря на то что метод toUpperCase() не принимает аргументов, он внутри себя знает, на каком объекте вызывается, и у него есть доступ к самому объекту.

Свойства

Кроме методов, у данных есть свойства. Свойство — это связанное с данными значение, к которому обращаются через точку сразу после переменной или константы. Например, у строк есть длина — свойство length:

const name = 'Robb';
const len = name.length;
console.log(len); // => 4

В предыдущих модулях для получения длины строки мы использовали учебную функцию length() из библиотеки hexlet-basics/string:

import { length } from 'hexlet-basics/string';

const name = 'Robb';
console.log(length(name)); // => 4

Это была временная замена — во многих языках длина строки действительно вычисляется через специальную функцию. В JavaScript же длина встроена прямо в язык как свойство .length. Начиная с этого урока учебная функция больше не понадобится: везде используем .length.

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

JavaScript позволяет обращаться к свойствам, которые не существуют (например, при опечатках). В таком случае их значением является undefined:

const name = 'Robb';
console.log(name.whatIsThat); // => undefined

Вопрос для самопроверки. Что распечатает код console.log(name[name.length]) для name, определённого выше? Почему ответ такой?

Ответ

Код распечатает undefined, потому что происходит обращение по индексу, который выходит за границу строки. В этом случае name.length — 4, а индекс последнего символа в строке — 3.

Методы строк

Методов у данных обычно значительно больше, чем свойств. У строк их несколько десятков, вот некоторые из них.

// Перевод всех букв в верхний регистр
console.log('hexlet'.toUpperCase()); // => HEXLET

// Перевод всех букв в нижний регистр
console.log('HeXleT'.toLowerCase()); // => hexlet

// Удаление пробелов в начале и конце строки
console.log('   hi   '.trim()); // => hi

Некоторые методы принимают параметры. Например, у метода replace() первый параметр содержит подстроку, которую нужно заменить, а второй — строку-замену.

const text = 'abracadabra';

// Заменяется только первое вхождение
console.log(text.replace('a', 'o'));    // => obracadabra
console.log(text.replace('abra', '!')); // => !cadabra

Методов в JavaScript действительно много, и их не учат наизусть. Обычно программисты в процессе работы запоминают, какие операции им вообще нужны и как примерно называются такие методы. При возникновении задачи они либо вспоминают подходящий метод, либо быстро находят его в документации.

Методы есть и у чисел

const temperature = 22.93;
// Округление до одного знака после запятой
const roundedTemperature = temperature.toFixed(1);
// Метод возвращает строку, которая содержит преобразованное число
console.log(roundedTemperature); // => 22.9

// Напрямую можно вызывать так
// Скобки нужны обязательно, иначе не заработает
(22.93).toFixed(1); // 22.9

Хозяйке на заметку. Технически всё несколько сложнее. Методы есть не у самих чисел, а у данных (объектов) типа Number. Числа, записанные в переменные или константы, автоматически преобразуются к данному типу во время обращения к ним — в это время происходит так называемый boxing.

Метод и функция: сравнение

С точки зрения кода методы и функции ведут себя похоже. Они принимают значения и возвращают результат. Отличаются только синтаксисом вызова.

// Вызов функции
Math.min(3, 5);

// Вызов метода
'hexlet'.toUpperCase();

Функция вызывается снаружи и получает аргументы в скобках. Метод представляет собой операцию, встроенную в само значение. Под капотом значение передаётся внутрь, но это скрыто от нас.

Возникает закономерный вопрос: зачем нужны методы, почему не просто функции? Есть две причины, почему так сложилось:

  1. Исторически так получилось. JavaScript разрабатывался слишком быстро, поэтому не всё было продумано хорошо.
  2. Далеко не все функции имеют отношение к конкретному значению. Возьмём для примера Math.min() — она находит минимальное среди переданных чисел. Делать её методом конкретного числа, например (1).min(), нелогично: она не связана с одним конкретным числом.

С другой стороны, функции, работающие с конкретным значением, для единообразия логично реализовывать как методы. JavaScript — язык, в котором прижились оба подхода: в нём активно используются как обычные функции, так и методы. Подробнее о плюсах и минусах этих подходов рассказывается в курсах, посвящённых ООП.

Методы возвращают значения

Как и функции, методы возвращают результат. Их можно использовать в составе выражений.

const name = 'hexlet';
console.log(name.toUpperCase() + '!'); // => HEXLET!

Методы строк всегда возвращают новую строку, оставляя исходную без изменений. Это поведение называется иммутабельностью. Мы ещё поговорим об этом в следующем уроке, но пока важно понимать, что строка остаётся прежней, а результат метода является новым значением.

const name = 'hexlet';
console.log(name.toUpperCase()); // => HEXLET
console.log(name);               // => hexlet

Свойства и методы в выражениях

Свойства и методы — такие же выражения, как переменные, константы или вызовы функций. Их можно использовать в арифметических операциях и передавать как аргументы другим функциям.

Использование в операциях:

const name = 'Shaya';
console.log(name.length + 5);          // => 10
console.log(`hi, ${name.toUpperCase()}!`); // => hi, SHAYA!

Использование как аргументов функций:

const firstName = 'Robb';
const lastName = 'Shaya';
// Передаём свойства прямо в вызов функции
console.log(Math.min(firstName.length, lastName.length)); // => 4

Это позволяет писать компактный и выразительный код, не сохраняя промежуточные результаты в отдельных переменных.

Задание

Пользователь ввёл текст с включённым caps lock — буквы в разном регистре. Перед сохранением программа приводит текст к нижнему регистру. Приведите строку из переменной text к нижнему регистру и выведите на экран. Пример метода, выполняющего эту задачу, приведён в теории.

Коммерческий опыт и Трудоустройство

Полезное

  • Методы строки

Команда проекта находится в телеграм-сообществе. Там можно задать любой вопрос и повлиять на проект

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются
← ПредыдущийСледующий →
← ПредыдущийСледующий →
← ПредыдущийСледующий →

Ваше упражнение проверяется по этим тестам

// @ts-check

import { expect, test, vi } from 'vitest';

test('objects', async () => {
  const consoleLogSpy = vi.spyOn(console, 'log');
  await import('./index.js');

  const firstArg = consoleLogSpy.mock.calls.join('\n');

  expect(firstArg).toBe(
    'a mind needs books as a sword needs a whetstone, if it is to keep its edge.',
  );
});
← ПредыдущийСледующий →

Решение учителя откроется через:

20:00

waiting_clock
← ПредыдущийСледующий →