← Назад к вопросам

Возможен ли вызов стрелочной функции через оператор new в JavaScript

1.0 Junior🔥 211 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Возможен ли вызов стрелочной функции через оператор new в JavaScript

Короткий ответ: НЕТ, стрелочные функции нельзя вызывать с оператором new. Это приведет к TypeError. Понимание этого различия критично для работы с классами и конструкторами.

Демонстрация проблемы

// Обычная функция - можно вызвать с new
function RegularFunction(name) {
  this.name = name;
}

const obj1 = new RegularFunction('Alice');
console.log(obj1.name); // 'Alice'

// Стрелочная функция - нельзя вызвать с new
const ArrowFunction = (name) => {
  this.name = name;
};

const obj2 = new ArrowFunction('Bob');
// TypeError: ArrowFunction is not a constructor

Почему это происходит

Это связано с тем, что стрелочные функции НЕ имеют собственного [[Construct]] внутреннего слота. Каждая функция в JavaScript имеет или не имеет этот слот:

Обычные функции:

  • Имеют [[Construct]] слот
  • Могут быть использованы как конструкторы
  • Имеют свойство prototype
  • При вызове с new создается новый объект
function MyConstructor() {
  this.value = 42;
}

console.log(MyConstructor.prototype); // { constructor: MyConstructor }
console.log(MyConstructor.hasOwnProperty('prototype')); // true

Стрелочные функции:

  • НЕ имеют [[Construct]] слота
  • Не могут быть конструкторами
  • НЕ имеют свойства prototype
  • Наследуют this из окружения (lexical this)
const myArrow = () => {
  this.value = 42;
};

console.log(myArrow.prototype); // undefined
console.log(myArrow.hasOwnProperty('prototype')); // false

Сравнение поведения

// Обычная функция
function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  return `Hello, ${this.name}`;
};

const person1 = new Person('Alice');
console.log(person1.greet()); // "Hello, Alice"
console.log(person1 instanceof Person); // true

// Стрелочная функция не может так работать
const PersonArrow = (name) => {
  this.name = name;  // this не привязан к объекту!
};

const person2 = new PersonArrow('Bob');
// TypeError: PersonArrow is not a constructor

Важная особенность: this в стрелочных функциях

Стрелочные функции наследуют this из лексического контекста, а не из контекста вызова:

const obj = {
  name: 'Object',
  
  // Обычная функция - this зависит от вызова
  regularMethod: function() {
    console.log(this.name); // "Object"
  },
  
  // Стрелочная функция - this из obj контекста
  arrowMethod: () => {
    console.log(this.name); // undefined (this = window/global)
  }
};

obj.regularMethod(); // "Object"
obj.arrowMethod();   // undefined

Когда использовать каждый тип

Используй обычную функцию, если:

  • Нужен конструктор
  • Нужно изменять this через call(), apply(), bind()
  • Нужно использовать в прототипе
class User {
  constructor(name) {
    this.name = name;
  }
  
  // Метод с обычной функцией
  greet() {
    return `Hello, ${this.name}`;
  }
}

const user = new User('Alice');
console.log(user.greet()); // "Hello, Alice"

Используй стрелочную функцию:

  • Для callback функций (где нужен родительский this)
  • Когда не нужно менять this
  • Для коротких функций
class Button {
  constructor(name) {
    this.name = name;
  }
  
  addClickListener() {
    // Стрелочная функция - this от Button
    button.addEventListener('click', () => {
      console.log(`${this.name} clicked`); // this = Button объект
    });
  }
}

Полное сравнение

ХарактеристикаОбычная функцияСтрелочная функция
Может быть конструкторомДаНЕТ
Имеет prototypeДаНет
Может использоваться с newДаОшибка
Может использоваться с call()/apply()Да (можно менять this)Да (но this не меняется)
this привязан кКонтексту вызоваЛексическому контексту
Может быть методомДаДа (но с особенностями)
Может быть callbackДаДа (часто предпочтительнее)

Классы и конструкторы (современный подход)

В современном JavaScript класс это синтаксический сахар над функциями-конструкторами:

// Класс (ES6+)
class Person {
  constructor(name) {
    this.name = name;
  }
  
  greet() {
    return `Hello, ${this.name}`;
  }
}

const person = new Person('Alice');
console.log(person.greet()); // "Hello, Alice"

// Эквивалентно (старый способ)
function PersonOld(name) {
  this.name = name;
}

PersonOld.prototype.greet = function() {
  return `Hello, ${this.name}`;
};

const personOld = new PersonOld('Alice');

Проверка, является ли функция конструктором

// Попытка использовать with try-catch
function isConstructor(fn) {
  try {
    new fn();
    return true;
  } catch (e) {
    return false;
  }
}

function RegularFunc() {}
const arrowFunc = () => {};

console.log(isConstructor(RegularFunc)); // true
console.log(isConstructor(arrowFunc));   // false

// Лучший способ - проверить prototype
function hasPrototype(fn) {
  return fn.hasOwnProperty('prototype');
}

console.log(hasPrototype(RegularFunc)); // true
console.log(hasPrototype(arrowFunc));   // false

Практический пример ошибки

// Неправильно - использование стрелочной функции как конструктора
const UserArrow = (name) => {
  this.name = name;
};

const user = new UserArrow('Alice');
// TypeError: UserArrow is not a constructor

// Правильно - используем class или обычную функцию
class User {
  constructor(name) {
    this.name = name;
  }
}

const user = new User('Alice'); // OK

// Или старый способ
function User(name) {
  this.name = name;
}

const user = new User('Alice'); // OK

Резюме для интервью

"Стрелочные функции нельзя вызвать с оператором new — это приведет к TypeError. Причина: стрелочные функции не имеют внутреннего [[Construct]] слота и не имеют собственного prototype. Они используются для callback функций, где нужен лексический this. Для конструкторов используй обычные функции или классы (которые синтаксический сахар над функциями).

Основное различие: обычная функция это и значение, и конструктор, а стрелочная — только значение."

Возможен ли вызов стрелочной функции через оператор new в JavaScript | PrepBro