본문 바로가기

Programming/JavaScript

Regular Functions vs. Arrow Functions

const sunny = {
  firstName: 'Sunny',
  year: 1988,
  calcAge: function () {
    console.log(this);
    console.log(2022 - this.year);
  },

  greet: () => console.log(`Hey ${this.firstName}`), // this arrow function does not have its own this keyword.
};
sunny.greet(); // Hey undefined
Arrow function does not get its own this keyword

It will simply use this keyword from its surroundings

= its parent's this keyword

 

여기서 greet method의 parent scope은 (jonas가 아닌) global scope임!

-> window object

console.log(this); // window object
console.log(this.firstName); // undefined

window object에서 firstName을 따로 정의한 바가 없음

so undefined가 출력됨!

 

What if jonas 밖에 firstName을 따로 정의해준다면?

var firstName = 'Matilda';

const sunny = {
  firstName: 'Sunny',
  year: 1988,
  calcAge: function () {
    console.log(this);
    console.log(2022 - this.year);
  },

  greet: () => {
    console.log(this);
    console.log(`Hey ${this.firstName}`);
  },
};
sunny.greet(); // Hey Matilda

sunny.greet();의 결과물이 Hey undefined가 아닌 Hey Matilda로 바뀐걸 알 수 있음!

Why? greet function을 call한건 sunny지만-

but arrow function에서는 sunny.firstName을 불러오지 않음!

 

console에 this를 log를 찍어보자.

그럼 window object의 firstName이 Matilda 값이 담긴 걸 알 수 있음!

Why? this.firstName translated window.firstName to Matilda

fistName을 var로 선언했기 때문에 this kind of global object 선언한거임

그래서 결론은?

그냥 arrow function 쓰지 말아라.

this keyword 안 쓸 때도!

어떤 종류의 function 쓰는지 고려안해도 되니까.

괜히 arrow function 썼다가 규칙도 다른데 헷갈리니 실수하는 수가 있음.

var firstName = 'Matilda';

const sunny = {
  firstName: 'Sunny',
  year: 1988,
  calcAge: function () {
    console.log(this);
    console.log(2022 - this.year);
  },

  greet: function () {
    console.log(this);
    console.log(`Hey ${this.firstName}`);
  },
};
sunny.greet(); // Hey Sunny

만약 arrow function이 아닌 greet: function ()으로 정의하면 sunny.greet()의 결과물이 Hey Matilda가 아닌 Hey Sunny로 바뀐걸 알 수 있음!


Even though it happens inside the method, this is how this keyword works with regular function.

=> 여기서 isMillenial 안에 있는 this가 가치 sunny object를 가리킬 것 같지만 아님.

Global scope를 가리키는데 global에 뭐 정의한게 없으니까 undefined가 나오는거다.

버그가 아님 🙅‍♀️

const sunny = {
  firstName: 'Sunny',
  year: 1988,
  calcAge: function () {
    // console.log(this);
    console.log(2022 - this.year);

    const isMillenial = function () {
      console.log(this); // undefined why? regular function call sets this as undefined
      console.log(this.year >= 1981 && this.year <= 1996); // Uncaught TypeError: Cannot read properties of undefined (reading 'year')
    };
    isMillenial();
  },

  greet: () => {
    console.log(this);
    console.log(`Hey ${this.firstName}`);
  },
};
sunny.greet();
sunny.calcAge();

two solutions

1. self로 변경함

const sunny = {
  firstName: 'Sunny',
  year: 1988,
  calcAge: function () {
    // console.log(this);
    console.log(2022 - this.year);

    const self = this; // self or that
    const isMillenial = function () {
      console.log(self); // {firstName: 'Sunny', year: 1988, calcAge: ƒ, greet: ƒ}
      console.log(self.year >= 1981 && self.year <= 1996); // true
      // console.log(this.year >= 1981 && this.year <= 1996);
    };
    isMillenial();
  },

  greet: () => {
    console.log(this);
    console.log(`Hey ${this.firstName}`);
  },
};
sunny.greet();
sunny.calcAge();

2.  const isMillenial = () =>

const sunny = {
  firstName: 'Sunny',
  year: 1988,
  calcAge: function () {
    // console.log(this);
    console.log(2022 - this.year);

    // Solution 1
    // const self = this; // self or that
    // const isMillenial = function () {
    //   console.log(self);
    //   console.log(self.year >= 1981 && self.year <= 1996);
    // };

    // Solution 2
    const isMillenial = () => {
      console.log(this); // {firstName: 'Sunny', year: 1988, calcAge: ƒ, greet: ƒ}
      console.log(this.year >= 1981 && this.year <= 1996); // true
    };
    isMillenial();
  },

  greet: () => {
    console.log(this);
    console.log(`Hey ${this.firstName}`);
  },
};
sunny.greet();
sunny.calcAge();

arguments only exist only in regular function

// arguments keyword
const addExpr = function (a, b) {
  console.log(arguments);
  return a + b;
};
addExpr(2, 5);
addExpr(2, 5, 8, 12);

var addArrow = (a, b) => {
  console.log(arguments);
  return a + b;
};
addArrow(2, 5, 8);