НейроАгент

Ключевое слово 'new' в JavaScript: Полное руководство

Освойте ключевое слово 'new' в JavaScript с нашим полным руководством. Узнайте о создании объектов, прототипном наследовании и лучших практиках для современного JavaScript-разработки.

Вопрос

Что такое ключевое слово ‘new’ в JavaScript и как оно работает?

Ключевое слово ‘new’ в JavaScript может быть запутанным для начинающих, особенно для тех, кто ошибочно считает, что JavaScript не является объектно-ориентированным языком программирования. Этот всеобъемлющий руководство призвано прояснить:

  • Что именно представляет собой ключевое слово ‘new’ в JavaScript?
  • Какие проблемы решает ключевое слово ‘new’ в разработке на JavaScript?
  • Когда следует использовать ключевое слово ‘new’, а когда его следует избегать?
  • Как ключевое слово ‘new’ влияет на создание объектов и наследование в JavaScript?
  • Какие существуют лучшие практики использования ключевого слова ‘new’ в современной разработке на JavaScript?
НейроАгент

Ключевое слово ‘new’ в JavaScript — это оператор, который создает новый объект и вызывает конструкторную функцию, автоматически связывая ключевое слово ‘this’ с вновь созданным объектом и устанавливая прототипное наследование. При использовании с функцией ‘new’ преобразует эту функцию в конструктор, создавая экземпляр, который наследует свойства и методы из прототипа конструктора, позволяя каждому экземпляру иметь свой собственный набор свойств на основе логики инициализации конструктора.


Содержание


Что именно представляет собой ключевое слово ‘new’ в JavaScript?

Ключевое слово ‘new’ — это оператор JavaScript, который создает экземпляр объекта. Технически любая функция (кроме стрелочных функций, которые не имеют собственного ‘this’) может использоваться в качестве конструктора при вызове с ‘new’. Общепринятой конвенцией в JavaScript является написание первой буквы конструкторных функций заглавной, чтобы указать, что их следует вызывать с помощью ‘new’, что делает ясным, что функция предназначена для использования в качестве конструктора источник.

Когда мы используем ‘new’, мы по сути сообщаем JavaScript, что следующую функцию следует рассматривать как конструктор, а не как обычный вызов функции. Это различие имеет решающее значение, поскольку оно меняет то, как 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 выполняет многоэтапный процесс в фоновом режиме:

  1. Создает пустой объект: Ключевое слово ‘new’ создает совершенно новый, пустой объект источник.

  2. Устанавливает связь с прототипом: Новый объект связывается со свойством prototype конструкторной функции, устанавливая наследование источник.

  3. Связывает ‘this’ с новым объектом: Внутри конструкторной функции ключевое слово ‘this’ теперь ссылается на вновь созданный объект, а не на глобальный объект источник.

  4. Выполняет конструкторную функцию: JavaScript запускает конструкторную функцию с предоставленными аргументами, позволяя инициализировать свойства нового объекта.

  5. Возвращает новый объект: Если не предоставлено явное возвращаемое значение (return), новый объект автоматически возвращается источник.

Вот визуальное представление того, что происходит при вызове new Person('Alice', 30):

javascript
// В фоновом режиме 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’ предоставляют эффективное решение:

javascript
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:

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’ со стрелочной функцией вызовет ошибку:

javascript
const ArrowConstructor = () => {};
const instance = new ArrowConstructor(); // TypeError: ArrowConstructor is not a constructor

Функции, не предназначенные в качестве конструкторов

Использование ‘new’ с обычными функциями, которые не были спроектированы как конструкторы, может привести к непредвиденному поведению:

javascript
function add(a, b) {
    return a + b;
}

const result = new add(2, 3); // Возвращает пустой объект, а не 5

Современный JavaScript с классами ES6

Хотя ‘new’ по-прежнему работает с классами ES6, многие разработчики предпочитают более чистый синтаксис:

javascript
// Вместо:
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 над моделью прототипного наследования:

javascript
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    
    greet() {
        return `Привет, меня зовут ${this.name}`;
    }
}

const person = new Person('Alice', 30);

Как отмечает один из разработчиков, “Использование ключевого слова class абсолютно совместимо с текущими лучшими практиками” источник.

Композиция объектов

Вместо того чтобы полагаться на наследование, многие современные разработчики JavaScript предпочитают композицию объектов:

javascript
const canEat = {
    eat() {
        console.log('Ем...');
    }
};

const canSleep = {
    sleep() {
        console.log('Сплю...');
    }
};

const person = {
    ...canEat,
    ...canSleep,
    name: 'Alice'
};

Фабричные функции

Фабричные функции предоставляют альтернативу конструкторным функциям с ‘new’:

javascript
function createPerson(name, age) {
    return {
        name,
        age,
        greet() {
            return `Привет, меня зовут ${this.name}`;
        }
    };
}

const person = createPerson('Alice', 30);

Модульный паттерн

Модульный паттерн обеспечивает инкапсуляцию без необходимости использования ‘new’:

javascript
const personModule = (function() {
    let name;
    let age;
    
    return {
        setName(n) {
            name = n;
        },
        setAge(a) {
            age = a;
        },
        getInfo() {
            return { name, age };
        }
    };
})();

Сводка лучших практик

  1. Используйте классы ES6 для нового кода: Они предоставляют более чистый синтаксис, сохраняя при том же прототипном наследовании “под капотом” источник.

  2. Рассмотрите альтернативы классам: Некоторые опытные разработчики утверждают, что “JavaScript достаточно хорош, чтобы предложить гораздо лучшие альтернативы, такие как композиция объектов и прототипное наследование” источник.

  3. Будьте последовательны: Какой бы подход вы ни выбрали, используйте его последовательно во всем кодовой базе.

  4. Понимайте базовые механизмы: Даже при использовании современного синтаксиса понимание того, как работают ‘new’ и прототипы, сделает вас лучшим разработчиком JavaScript.


Заключение

Ключевое слово ‘new’ в JavaScript — это мощный оператор, который создает объекты и устанавливает прототипное наследование, но оно не всегда является лучшим выбором для современного JavaScript-разработки. Ключевые выводы включают:

  • Ключевое слово ‘new’ создает объект, связывает ‘this’ с этим объектом, настраивает прототипное наследование и возвращает новый экземпляр
  • Хотя оно необходимо для понимания объектной модели JavaScript, многие разработчики теперь предпочитают классы ES6 как современный стандарт
  • Композиция объектов, фабричные функции и модульный паттерн предоставляют альтернативы традиционным конструкторным функциям
  • Лучший подход зависит от ваших конкретных потребностей, предпочтений команды и сложности вашего приложения

Независимо от того, работаете ли вы с устаревшим кодом или начинаете с нуля, понимание того, как работает ‘new’, поможет вам принимать обоснованные решения о создании объектов и наследовании в JavaScript.


Источники

  1. JavaScript.info - Конструктор, оператор “new”
  2. MDN - Оператор new
  3. DigitalOcean - Понимание прототипов и наследования в JavaScript
  4. Stack Overflow - Что такое ключевое слово ‘new’ в JavaScript?
  5. Mbloging - Понимание ключевого слова new в JavaScript
  6. Stack Overflow - Создание объектов JavaScript с помощью ключевого слова ‘new’
  7. Reddit - Использование классов в JavaScript (ES6) — лучшая практика?
  8. Stack Overflow - Считается ли ключевое слово “new” в JavaScript вредным?
  9. GitHub - Нам лучше избегать классов ES6 в JavaScript, когда это возможно
  10. Medium - Ключевое слово new в JavaScript, под капотом