Javascript this keyward

This 란?

This 는 모든 실행 컨텍스트(모든 함수)에 대해 생성되는 특별한 값이다.
그리고 this 키워드가 사용된 함수의 "owner" 의 값을 가진다



this는 값이 똑같지 않다. this 의 값은 함수가 어떻게 호출됬는지에 따른다. 그리고 this의 값은 오직 함수가 실제로 호출될 때만 할당된다.


Method => this 는 method를 소유한 객체를 가르킨다.

Simple function call => this = undefined (엄격 모드에서만 해당된다. 아닐 경우 전역 객체인 window 의 값을 가져온다.)

Arrow function => this = lexical this 이다. 즉, 자신을 둘러싼 환경의 this 를 그대로 승계받는다.


Event Listener = > this => handler 함수가 붙어 있는 DOM 요소이다.

new,call,apply,bind => later course..




this 는 사용하고 있는 함수를 절대 가르키지 않는다.

또한 함수의 variable environment를 절대 가르키지 않는다.

1
2
3
4
5
6
7
8
9
10
11
12
const jonas = {
  firstName: 'Jonas',
  year: 1991,
  calcAge: function () {
    console.log(this);
    console.log(2037 - this.year);
  },
 
  greet: () => console.log(`Hey ${this.firstName}`),
};
jonas.greet(); //Hey undefined
console.log(this.firstName); //undefined
                cs

예제와 함께 알아보자

두 값이 모두 undefined 가 나온다. 이유를 알아보자.
greet 함수는 arrow function으로 arrow function  은 자기 소유의 this 를 갖지 못한다. 단순하게 하자면 함수 스코프의 영향을 받지 않고 주위 코드에서 쓰이는 this 와 같은 값을 가진다. 참고로 객체의 코드 블럭은 block scoping이 아니다. 따라서 greet 함수의 this는 window 전역 객체를 가르킨다. 따라서 window.firstName이 된다. 이때 var을 잘 사용하지 않는 이유가 나온다. 만약 var firstName을 객체 위에서 선언했더라면 firstName은 window에 property 로 선언되고 이는 찾기 힘든 오류가 생성된다. 하지만 let , const는 window에 특성으로 선언되지 않으므로 안심하고 사용할 수 있다. 

this.firstName이 undefined가 나오는 이유는 마찬가지로 여기서의 this 는 window를 가르키고 window 에는 firstName 이라는 property가 없으므로 window.firstName = undefined를 가져오게 된다.


이런 오류를 예방하기 위해선 단순히 arrow function을 method로 사용하지 않으면 해결된다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const jonas = {
  firstName: 'Jonas',
  year: 1991,
  calcAge: function () {
    console.log(this);
 
    const isMillenial = function () {
      console.log(this);
    };
 
    isMillenial();
  },
};
 
jonas.calcAge();
 
cs

이번 상황의 this는 좀 다르다. method 안에 표현형 함수를 정의 했고 그 함수 안에 this 를 사용했다. 

결과는 undefined 이다. 일반 상황의 함수에서 this 를 사용하면 undefined 이다. 따라서 매쏘드 안에 있더라도 this 는 일반 상황의 함수안에 있으므로 undefined 의 값이 나오게 된다.


이를 해결하기 위한 방안은 2가지가 있다.


첫번째는 추가적인 변수를 활용하는 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const jonas = {
  firstName: 'Jonas',
  year: 1991,
  calcAge: function () {
    console.log(this);
    const self = this;
    const isMillenial = function () {
      console.log(self);
    };
 
    isMillenial();
  },
};
 
jonas.calcAge();
cs

위 와 다르게 코드 const self = this; 를 추가했다. this는 동적인 변수이다. 그러므로 매쏘드 안에의 this 는 올바르게 객체 jonas를 가르킨다. 하지만 this가 일반 함수에서 사용 되면 undefined를 가지게 된다. 따라서 매쏘드 안에서의 this 값을 self 에 저장하고 일반 함수 안에서는 self 를 사용하면 해결할 수 있는 문제이다.



두번째는 arrow function을 사용하는 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const jonas = {
  firstName: 'Jonas',
  year: 1991,
  calcAge: function () {
    console.log(this);
    const self = this;
 
    const isMillenial = () => {
      console.log(this);
    };
 
    isMillenial();
  },
};
jonas.calcAge();
      cs

위에선 isMillenial 함수는 일반 함수로 선언하였지만 지금의 함수는 arrow function 을 이용하였다. 앞서 말했듯 arrow function을 이용하면 오해의 표현일 순 있지만 함수를 쓰지 않은 것처럼 this를 사용할 수 있다. (=arrow function의 parent scope를 따른다와 같은 의미이다.)따라서 매쏘드 안에 있는 this 가 되므로 arrow function 을 이용하여 문제를 해결 할 수 있다.






이번엔 arguments 키워드에 대해 알아보자!

arguments 키워드는 함수의 인자를 가져오는 역할을 한다. 여러 인수들이 있으면 이를 배열 형태로 저장하므로 여러 인자가 있을때 유리하게 사용 할 수 있다.

this 키워드 와는 다르게 일반 함수 형태에서만 사용할 수 있고 arrow 함수에서는 사용이 불가능하다.


1
2
3
4
5
6
7
8
9
10
11
12
const add1 = function (a, b) {
  console.log(arguments);
  return a + b;
};
add1(2, 5);
add1(2, 5, 8, 10);
 
var addArrow = (a, b) => {
  console.log(arguments);
  return a + b;
};
addArrow(2, 5);
       cs

함수 선언식에서는 arguments 키워드가 정상 작동하지만 아래의 화살표 함수에서는 오류가 발생한다.




















댓글

이 블로그의 인기 게시물

Javascript Object vs Primitives (Primitives vs reference type)

javascript 15 switch statement