Что такое ключевое слово ‘new’ в JavaScript и как оно работает?
Ключевое слово ‘new’ в JavaScript может быть запутанным для начинающих, особенно для тех, кто ошибочно считает, что JavaScript не является объектно-ориентированным языком программирования. Этот всеобъемлющий руководство призвано прояснить:
- Что именно представляет собой ключевое слово ‘new’ в JavaScript?
- Какие проблемы решает ключевое слово ‘new’ в разработке на JavaScript?
- Когда следует использовать ключевое слово ‘new’, а когда его следует избегать?
- Как ключевое слово ‘new’ влияет на создание объектов и наследование в JavaScript?
- Какие существуют лучшие практики использования ключевого слова ‘new’ в современной разработке на JavaScript?
Ключевое слово ‘new’ в JavaScript — это оператор, который создает новый объект и вызывает конструкторную функцию, автоматически связывая ключевое слово ‘this’ с вновь созданным объектом и устанавливая прототипное наследование. При использовании с функцией ‘new’ преобразует эту функцию в конструктор, создавая экземпляр, который наследует свойства и методы из прототипа конструктора, позволяя каждому экземпляру иметь свой собственный набор свойств на основе логики инициализации конструктора.
Содержание
- Что именно представляет собой ключевое слово ‘new’ в JavaScript?
- Как работает ключевое слово ‘new’: пошаговое объяснение
- Проблемы, которые решает ключевое слово ‘new’
- Когда использовать ключевое слово ‘new’
- Когда следует избегать использования ключевого слова ‘new’
- Современные альтернативы и лучшие практики
Что именно представляет собой ключевое слово ‘new’ в JavaScript?
Ключевое слово ‘new’ — это оператор JavaScript, который создает экземпляр объекта. Технически любая функция (кроме стрелочных функций, которые не имеют собственного ‘this’) может использоваться в качестве конструктора при вызове с ‘new’. Общепринятой конвенцией в JavaScript является написание первой буквы конструкторных функций заглавной, чтобы указать, что их следует вызывать с помощью ‘new’, что делает ясным, что функция предназначена для использования в качестве конструктора источник.
Когда мы используем ‘new’, мы по сути сообщаем JavaScript, что следующую функцию следует рассматривать как конструктор, а не как обычный вызов функции. Это различие имеет решающее значение, поскольку оно меняет то, как JavaScript обрабатывает выполнение функции и процесс создания объекта.
function Person(name, age) {
this.name = name;
this.age = age;
}
const person1 = new Person('Alice', 30);
const person2 = new Person('Bob', 25);
В этом примере ‘Person’ — это конструкторная функция, которая при вызове с ‘new’ создает новые экземпляры со своими собственными свойствами ‘name’ и ‘age’.
Как работает ключевое слово ‘new’: пошаговое объяснение
При использовании ключевого слова ‘new’ с функцией JavaScript выполняет многоэтапный процесс в фоновом режиме:
-
Создает пустой объект: Ключевое слово ‘new’ создает совершенно новый, пустой объект источник.
-
Устанавливает связь с прототипом: Новый объект связывается со свойством prototype конструкторной функции, устанавливая наследование источник.
-
Связывает ‘this’ с новым объектом: Внутри конструкторной функции ключевое слово ‘this’ теперь ссылается на вновь созданный объект, а не на глобальный объект источник.
-
Выполняет конструкторную функцию: JavaScript запускает конструкторную функцию с предоставленными аргументами, позволяя инициализировать свойства нового объекта.
-
Возвращает новый объект: Если не предоставлено явное возвращаемое значение (return), новый объект автоматически возвращается источник.
Вот визуальное представление того, что происходит при вызове new Person('Alice', 30):
// В фоновом режиме JavaScript делает что-то вроде этого:
const person = {
__proto__: Person.prototype
};
Person.call(person, 'Alice', 30);
return person;
Этот процесс гарантирует, что каждый новый экземпляр сохраняет свои собственные свойства, при этом разделяя методы и другие свойства из цепочки прототипов.
Проблемы, которые решает ключевое слово ‘new’
Ключевое слово ‘new’ решает несколько фундаментальных задач в объектно-ориентированном программировании JavaScript:
Правильная привязка ‘this’
Без ‘new’ вызов конструкторной функции привел бы к тому, что ‘this’ ссылался бы на глобальный объект (или был undefined в строгом режиме), потенциально засоряя глобальное пространство имен или вызывая ошибки. Ключевое слово ‘new’ гарантирует, что ‘this’ правильно ссылается на вновь созданный объект источник.
Прототипное наследование
JavaScript использует прототипное наследование, а не классическое. Ключевое слово ‘new’ автоматически настраивает цепочку прототипов, позволяя экземплярам наследовать свойства и методы из прототипа конструктора источник.
Создание и инициализация объектов
До появления ‘new’ создание нескольких похожих объектов требовало повторяющегося кода. Ключевое слово ‘new’ предоставляет структурированный способ создания и инициализации нескольких экземпляров одного и того же типа объекта с последовательным поведением.
Эффективность использования памяти
Благодаря тому, что методы разделяются через прототип, а не дублируются в каждом экземпляре, ключевое слово ‘new’ помогает создавать более эффективный с точки зрения памяти код.
Когда использовать ключевое слово ‘new’
Создание нескольких похожих объектов
Когда вам нужно создать несколько объектов, которые разделяют общие свойства и методы, конструкторные функции с ‘new’ предоставляют эффективное решение:
function Product(name, price) {
this.name = name;
this.price = price;
}
Product.prototype.display = function() {
console.log(`${this.name}: $${this.price}`);
};
const laptop = new Product('Laptop', 999);
const phone = new Product('Phone', 699);
Установление иерархий наследования
Ключевое слово ‘new’ необходимо для создания цепочек наследования в JavaScript:
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} издает звук`);
};
function Dog(name, breed) {
Animal.call(this, name); // Вызов родительского конструктора
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
const myDog = new Dog('Rex', 'Немецкая овчарка');
Поддержание чистой структуры кода
Использование ‘new’ с конструкторными функциями помогает организовать код, четко разделяя создание объекта от его поведения, что делает код более читаемым и поддерживаемым.
Когда следует избегать использования ключевого слова ‘new’
Стрелочные функции
Стрелочные функции нельзя использовать в качестве конструкторов, поскольку они не имеют собственного контекста ‘this’. Попытка использовать ‘new’ со стрелочной функцией вызовет ошибку:
const ArrowConstructor = () => {};
const instance = new ArrowConstructor(); // TypeError: ArrowConstructor is not a constructor
Функции, не предназначенные в качестве конструкторов
Использование ‘new’ с обычными функциями, которые не были спроектированы как конструкторы, может привести к непредвиденному поведению:
function add(a, b) {
return a + b;
}
const result = new add(2, 3); // Возвращает пустой объект, а не 5
Современный JavaScript с классами ES6
Хотя ‘new’ по-прежнему работает с классами ES6, многие разработчики предпочитают более чистый синтаксис:
// Вместо:
function Car(make, model) {
this.make = make;
this.model = model;
}
Car.prototype.start = function() {
console.log('Двигатель запущен');
};
// Используйте:
class Car {
constructor(make, model) {
this.make = make;
this.model = model;
}
start() {
console.log('Двигатель запущен');
}
}
Современные альтернативы и лучшие практики
Классы ES6
Современный подход к созданию объектов в JavaScript — использование классов ES6, которые предоставляют syntactic sugar над моделью прототипного наследования:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Привет, меня зовут ${this.name}`;
}
}
const person = new Person('Alice', 30);
Как отмечает один из разработчиков, “Использование ключевого слова class абсолютно совместимо с текущими лучшими практиками” источник.
Композиция объектов
Вместо того чтобы полагаться на наследование, многие современные разработчики JavaScript предпочитают композицию объектов:
const canEat = {
eat() {
console.log('Ем...');
}
};
const canSleep = {
sleep() {
console.log('Сплю...');
}
};
const person = {
...canEat,
...canSleep,
name: 'Alice'
};
Фабричные функции
Фабричные функции предоставляют альтернативу конструкторным функциям с ‘new’:
function createPerson(name, age) {
return {
name,
age,
greet() {
return `Привет, меня зовут ${this.name}`;
}
};
}
const person = createPerson('Alice', 30);
Модульный паттерн
Модульный паттерн обеспечивает инкапсуляцию без необходимости использования ‘new’:
const personModule = (function() {
let name;
let age;
return {
setName(n) {
name = n;
},
setAge(a) {
age = a;
},
getInfo() {
return { name, age };
}
};
})();
Сводка лучших практик
-
Используйте классы ES6 для нового кода: Они предоставляют более чистый синтаксис, сохраняя при том же прототипном наследовании “под капотом” источник.
-
Рассмотрите альтернативы классам: Некоторые опытные разработчики утверждают, что “JavaScript достаточно хорош, чтобы предложить гораздо лучшие альтернативы, такие как композиция объектов и прототипное наследование” источник.
-
Будьте последовательны: Какой бы подход вы ни выбрали, используйте его последовательно во всем кодовой базе.
-
Понимайте базовые механизмы: Даже при использовании современного синтаксиса понимание того, как работают ‘new’ и прототипы, сделает вас лучшим разработчиком JavaScript.
Заключение
Ключевое слово ‘new’ в JavaScript — это мощный оператор, который создает объекты и устанавливает прототипное наследование, но оно не всегда является лучшим выбором для современного JavaScript-разработки. Ключевые выводы включают:
- Ключевое слово ‘new’ создает объект, связывает ‘this’ с этим объектом, настраивает прототипное наследование и возвращает новый экземпляр
- Хотя оно необходимо для понимания объектной модели JavaScript, многие разработчики теперь предпочитают классы ES6 как современный стандарт
- Композиция объектов, фабричные функции и модульный паттерн предоставляют альтернативы традиционным конструкторным функциям
- Лучший подход зависит от ваших конкретных потребностей, предпочтений команды и сложности вашего приложения
Независимо от того, работаете ли вы с устаревшим кодом или начинаете с нуля, понимание того, как работает ‘new’, поможет вам принимать обоснованные решения о создании объектов и наследовании в JavaScript.
Источники
- JavaScript.info - Конструктор, оператор “new”
- MDN - Оператор new
- DigitalOcean - Понимание прототипов и наследования в JavaScript
- Stack Overflow - Что такое ключевое слово ‘new’ в JavaScript?
- Mbloging - Понимание ключевого слова new в JavaScript
- Stack Overflow - Создание объектов JavaScript с помощью ключевого слова ‘new’
- Reddit - Использование классов в JavaScript (ES6) — лучшая практика?
- Stack Overflow - Считается ли ключевое слово “new” в JavaScript вредным?
- GitHub - Нам лучше избегать классов ES6 в JavaScript, когда это возможно
- Medium - Ключевое слово new в JavaScript, под капотом