@narem

Можно ли как-то заменить стрелочную функцию?

function getFIO(name, surname, patronymic){
    this.name = name,
    this.surname = surname,
    this.patronymic = patronymic,
    this.sayHello = () => {
        console.log(`Меня зовут ${this.surname} ${this.name} ${this.patronymic}`);
    }
}

var getFio = new getFIO('Юрий', 'Горячев', 'Александрович');
getFio.sayHello();

не совсем понимаю как работает этот кусок
this.sayHello = () => {
        console.log(`Меня зовут ${this.surname} ${this.name} ${this.patronymic}`);
    }

Попытался почитать про стрелочные функции, но недопонял. Может кто по простому объяснить?
  • Вопрос задан
  • 621 просмотр
Решения вопроса 2
notiv-nt
@notiv-nt
Как ваше ничего? Да, моё тоже
5d2f76e90694c180502066.png

Babel приведет это к такому виду

function getFIO(name, surname, patronymic){
  this.name = name;
  this.surname = surname;
  this.patronymic = patronymic;

  var that = this;

  this.sayHello = function() {
    console.log(`Меня зовут ${that.surname} ${that.name} ${that.patronymic}`);
  }
}
Ответ написан
Комментировать
Стрелочная функция это просто синтаксический сахар для привязки контекста выполнения функции.
Давайте по порядку. До ES2015 писали вот так:
function getFIO(name, surname, patronymic) {
  this.name = name,
  this.surname = surname,
  this.patronymic = patronymic,
  this.sayHello = function() {
    console.log(`Меня зовут ${this.surname} ${this.name} ${this.patronymic}`);
  }
}

var getFio = new getFIO('Юрий', 'Горячев', 'Александрович');
getFio.sayHello();

И все прекрасно работало до тех пор пока мы не начинали вызывать функцию `sayHello()` с другим контекстом. Например:
var getFio = new getFIO('Юрий', 'Горячев', 'Александрович');

var sayHello = getFio.sayHello;
sayHello() // в this теперь не объект getFio, а undefined

// или

someElement.addEventListener('click', getFio.sayHello, true) // контекст опять потерялся

Чтобы это исправить в конструкторе класса явно сохраняли контекст и передавали в функцию через замыкание:
function getFIO(name, surname, patronymic) {
   var that = this // сохранили контекст в локальной переменной

  this.name = name,
  this.surname = surname,
  this.patronymic = patronymic,
  this.sayHello = function() {
    console.log(`Меня зовут ${that.surname} ${that.name} ${that.patronymic}`); // теперь как бы ни вызвали эту функцию она всегда будет брать контекст из замыкания
  }
}

// или

function getFIO(name, surname, patronymic) {
   var sayHello = function() {
    console.log(`Меня зовут ${this.surname} ${this.name} ${this.patronymic}`);
  }

  this.name = name,
  this.surname = surname,
  this.patronymic = patronymic,
  this.sayHello = sayHello.bind(this) // явно указываем контекст выполнения функции
}


Чтобы избавится от этих проблем ввели стрелочные функции которые сохраняют контекст в котором они были объявлены.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
xEpozZ
@xEpozZ
Веб-разработчик
var a = () => {} - это объявление функции, на которую ссылается переменная a
var a = () => {} эквивалентно var a = function(){}

В вашем примере
this.sayHello = () => {
    console.log(`Меня зовут ${this.surname} ${this.name} ${this.patronymic}`);
}

вы в this.sayHello присваиваете функцию.
Это эквивалентно
this.sayHello = function() {
    console.log(`Меня зовут ${this.surname} ${this.name} ${this.patronymic}`);
}

только здесь this будет работать неправильно, потому что в стрелочную функцию this попадет как this из функции getFIO, а в обычную функцию попадет как this анонимной функции (на которую ссылается sayHello)
Ответ написан
Комментировать
maksipes
@maksipes
Если написать sayHello обычной функцией - свойств не будет найдено, ибо у этой функции будет свой this, отличный от функции лежащей выше - у каждой из них есть свой this.

У стрелочных функций своего this нет, следовательно this будет искаться дальше на уровень выше. И вот тут получается, что найдется this "родительской" функции, который как раз и нужен.

Стрелочная функция всегда "видит" this объекта/функции, где была объявлена.

Так я себе представляю это. Не претендую на точность.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы