일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- break문
- Step2
- 이클립스
- array
- 자바
- hanq
- javascript
- position
- web
- 전자정부프레임워크
- 취업반
- 자바스크립트
- continue문
- 유튜브 올리버쌤
- 삼항연산자
- JDK
- 유뷰브 올리버쌤
- for문
- 한큐에자바
- 이벤트핸들러
- Youtube 올리버쌤
- spread operator
- java
- math
- es6
- 올리버쌤
- 한큐
- egov
- Event
- 이벤트
- Today
- Total
호다닥
Javascript : 초보자를 위한 'This' 본문
The Keyword ‘This’ for Beginners
출처 : codeburst.io, Brandon Morelli
해당 내용은 Brandon Morelli의 article을 개인적으로 번역한 내용이며, 잘못 번역된 부분이 있을 수 있습니다. 원문은 위에 적힌 주소에서 확인하실 수 있습니다.
This 는 다소 복잡한 개념이지만, 이제부터 설명할 5가지 일반적인 법칙을 이해한다면 this 를 어떻게 사용할지, 언제 사용할 지 결정하는데 도움이 될 것이다.
물론 이 법칙들이 모든 경우를 설명할 수 있는 것은 아니지만 특수한 경우를 제외하면 대부분의 상황에서 도움이될 것이다.
#Global Object
크롬 개발자 콘솔을 열고 Console.log(this); 를 입력하면 // Window {...} 가 출력된다.
전역스코프에서 this는 global object를 의미하기 때문에 window 객체가 출력되는 것이다.
브라우저에서 global object는 window object이다.
this가 왜 window object를 나타내는지 좀더 자세히 이해하기 위해 좀 더 깊게 들어가보자.
콘솔에서 새로운 변수를 만들고 변수에 이름을 할당한다.
var myName = 'Jun';
우리는 변수 호출을 통해 이 새로운 변수를 가져올 수 있다.
myName
// returns -> 'Jun'
전역스코프에서 선언한 모든 변수는 window object가 된다.
window.myName
// returns -> 'Jun'
window.myName ===myName
// returns -> true
앞서 global context에서 consloe.log(this) 를 실행함으로써 우리는 this가 global object에서 호출됨을 알았다.
console.log(this)
// returns -> window {...}
이제 함수 내부에 this를 넣어보고자 한다. this의 value는 함수가 어떻게 호출되냐에 따라 결정된다.
그러면 함수 내부에 this가 있는 함수는 어떻게 return될 것인가 알아보기 위해 아래 코드를 브라우저 콘솔에 입력해보자.
function test () {
return this;
}
test()
다시 한번 this는 global(window) object를 return한다.
여기서 this는 선언된 객체의 내부에 있지 않기 때문에 기본적으로 global(window) object이다.
만약 strict mode에서 위 함수를 실행하면 this는 undefined가 될 것이다.
#2 Declared Object
만약 this가 선언된 객체의 내부에서 사용되면 this의 value는 호출된 method의 closet parent object이다.
아래 코드에서 object 객체를 선언하고 full method 내부에서 this를 사용했다.
var person = {
first: 'John',
last: 'Smith',
full: function() {
console.log(this.first + ' ' + this.last);
}
};
person.full();
// logs => 'John Smith'
this에 대해 좀 더 깊게 알아보기 위해 console.log(this)를 대신 사용하였다. 아래 코드를 복사하여 브라우저 콘솔에서 실행시켜 return값을 확인해보자.
var person = {
first: 'John',
last: 'Smith',
full: function() {
console.log(this);
}
};
person.full();
// logs => Object {first: "John", last: "Smith", full: function}
콘솔에서 person object가 return되고 this가 person의 value로 사용되었음을 확인할 수 있을 것이다.
만약 중첩된 objects을 가지고 있다면 어떤 값을 기대할 수 있을까? 아래 예제 코드를 통해 확인해보자.
우리는 위 코드와 마찬가지로 first, last, full 로 동일한 key값을 가진 person 객체를 가지고 있다. 그리고 중첩된 personTwo object를 가지고 있다. personTwo 역시 동일한 세가지 key값을 가지고 있다.
var person = {
first: 'John',
last: 'Smith',
full: function() {
console.log(this.first + ' ' + this.last);
},
personTwo: {
first: 'Allison',
last: 'Jones',
full: function() {
console.log(this.first + ' ' + this.last);
}
}
};
만약 full method들을 호출한다면 어떤 결과값이 호출될까?
person.full();
// logs => 'John Smith'
person.personTwo.full();
// logs => 'Allison Jones'
this의 value는 호출된 method의 closest parent object가 된다.
person.full() 이 호출되면 내부 함수의 this person object에 bound된다. 반면에, person.personTwo.full()로 내부의 full 함수를 호출하면 this는 personTwo object에 바운드 된다.
#3 The New Keyword
new가 생성자 함수로 사용된다면 this는 새로 만들어진 object에 bound된다.
function Car(make, model) {
this.make = make;
this.model = model;
};
위 예제 코드에서 this가 global object에 bound 되었다. ( new keyword를 사용하기 전까지는.. )
new를 사용하면 this의 value는 빈 객체가 된다. 아래 예제에서는 myCar가 된다.
var myCar = new Car('Ford', 'Escape');
console.log(myCar);
// logs => Car {make: "Ford", model: "Escape"}
이것을 이해하기 위해서는 new keyword에 대해 정확히 이해할 필요가 있다.
new keyword를 확인하면 this는 새로 만들어진 빈 객체임을 기억해라.
#4 Call, Bind, Apply
call, bind, apply를 사용하여 this의 value 값을 좀 더 명확하게 할 수 있다.
이 세가지는 유사하지만 사소한 차이를 이해하는 것이 중요하다.
call 과 apply는 즉시 호출한다. Call은 parameter의 숫자를 this 로 한다.
apply는 오직 2가지의 parameter만 가지는데 this와 더해지는 argument들의 배열이 그것들이다.
아래 예제코드를 통해 좀 더 확실히 이해해보도록 하자. 우리는 숫자들을 add할 것이다.
아래 코드를 복사하여 브라우저콘솔에 실행하고 함수를 호출해보자.
function add(c, d) {
console.log(this.a + this.b + c + d);
}
add(3,4);
// logs => NaN
add 함수는 NaN을 기록한다. 이는 this.a와 this.b가 undefined이기 때문이다. 이 두 변수들은 존재하지 않는다. 그리고 undefined인 변수에 숫자를 add할 수 없다.
우리는 객체와 함수를 호출하기 위해 call(0과 apply() 를 사용할 수 있다.
function add(c, d) {
console.log(this.a + this.b + c + d);
}
var ten = {a: 1, b: 2};
add.call(ten, 3, 4);
// logs => 10
add.apply(ten, [3,4]);
// logs => 10
우리가 add.call()을 사용할 때 첫번째 인자는 this로 bound 된다.
그 다음 parameter들은 우리가 호출하는 함수 내부로 들어가게 된다.
따라서, add() 에서 this.a는 ten.a가 되고, this.b는 ten.b가 된다. 그리고 우리는 1+2+3+4 또는 10을 return값으로 받는다.
add.apply() 도 유사하다. 첫번째 parameter는 this에 bound된다.
그리고 그 다음 parameter는 argument들의 배열로 함수에서 사용된다.
Bind는 어떻게 될까? bind() 의 parameter들은 call() 과 동일하지만 bind()는 즉시 호출되지 않는다. 대신 bind() 는 이미 bound 된 this의 context와 함께 함수를 return한다. 이런 점 때문에 bind()는 우리가 모든 argument들을 알지 못할 때 유용하게 사용된다.
이해를 돕기위해 다시 다음 예제를 확인해보자.
var small = {
a: 1,
go: function(b,c,d){
console.log(this.a+b+c+d);
}
}
var large = {
a: 100
}
콘솔에 위 코드를 입력한 후, 아래 코드를 호출해보자.
small.go(2,3,4);
// logs 1+2+3+4 => 10
그러나 만약 우리가 large.a의 value를 대신 사용하고 싶다면? call/apply를 사용하면 된다.
small.go.call(large,2,3,4);
// logs 100+2+3+4 => 109
만약 우리가 3 argument들을 모두 알지 못한다면? bind를 사용하면 된다.
var bindTest = small.go.bind(large,2);
console.log를 통해 위의 변수 bindTest를 호출하면 우리는 아래와 같은 결과값을 확인할 수 있다.
console.log(bindTest);
// logs => function (b,c,d){console.log(this.a+b+c+d);}
bind는 this가 bound 된 함수를 return한다는 것을 기억해라.
this 는 large object에 성공적으로 bound 된다. 그리고 두번째 argument로는 이미 숫자 2가 할당되어 있다.
이후 나머지 argument들을 알게되면 우리는 그것들을 추가적으로 할당할 수 있다.
bindTest(3,4);
// logs 100+2+3+4 => 109
위에서의 설명들을 다시 한번 확인하기 위해 위에서 배운 코드들을 모두 사용하여 하나의 block 내부에 작성하였다. 콘솔에 확인해봄으로써 결과값을 확인해보자.
var small = {
a: 1,
go: function(b,c,d){
console.log(this.a+b+c+d);
}
}
var large = {
a: 100
}
small.go(2,3,4);
// logs 1+2+3+4 => 10
var bindTest = small.go.bind(large,2);
console.log(bindTest);
// logs => function (b,c,d){console.log(this.a+b+c+d);}
bindTest(3,4);
// logs 100+2+3+4 => 109
#5 Arrow Function
화살표 함수에 대해서는 추후에 따로 공부할 것이다.
Conclusion
이제 대부분의 상황에서 this에 무엇이 들어가게 되는지 추론할 수 있을 것이다.
넘어가기 전에 다음 몇가지를 반드시 기억해라.
- this의 value는 대부분 함수의 실행 컨텍스트에 의해 결정된다.
- global 스코프에서 this는 global object이다. ( window 객체)
- 생성자 함수 new가 사용되면 this에 새로 만들어진 객체가 bound된다.
- 우리는 call(), bind(), apply()를 통해 this의 value를 설정할 수 있다.
- 화살표 함수는 this를 bind하지 않는다. 대신 this는 사전적으로 bound 된다. ( 원래 context에 기반하여 )
'Javascript' 카테고리의 다른 글
Javascript: 초보자를 위한 템플릿 리터럴 & 태그 기능 (0) | 2018.08.09 |
---|---|
Javascript: 초보자를 위한 정규식(Regular Expressions) 배우기 (0) | 2018.08.07 |
초보자를 위한 Javascript: 'new' 예약어 (4) | 2018.08.02 |
Javascript : 도대체 IIFE가 뭐야? (0) | 2018.07.26 |
Javascript : 초보자를 위한 화살표 함수 (0) | 2018.07.21 |