-
this 키워드
this는 함수 실행 시 호출(invocation) 방법에 의해 결정되는 특별한 객체
함수 실행 시 결정되므로, 실행되는 맥락(execution context)에 따라 this는 다르게 결정된다.- 브라우저 환경에서 this는 기본적으로 window 객체를 가리킨다.
- 객체의 메서드 a안의 this는 객체를 가리킨다.
위의 예제에서 다음과 같이 하면 결과가 달라진다.
호출할 때, 호출하는 함수가 객체의 메서드인지 그냥 함수인지가 중요하다. a2는 obj.a를 꺼내온 것이기 때문에 더 이상 객체의 메서드가 아닌 것이다.
- this를 바꾸는 함수 메서드인 bind, call, apply를 사용하면 this는 객체를 가리킨다.
- 생성자 함수에서 new를 사용하지 않고 호출하는 경우에는 this는 window가 된다.
(new를 붙이면 this는 생성자를 통해 생성된 인스턴스가 된다)
- node.js 환경에서 this는 기본적으로 module.exports 객체를 가리킨다.
함수 실행의 다섯 가지 방법
함수가 무엇이냐가 중요한 것이 아니라, 어떻게 실행되는 것인지가 중요하다.
1. Global: 정확히 말하면 함수 실행은 아니고, 전역에서 this를 참조할 때를 의미
console.log(this);
2. Function 호출
foo();
3. Method 호출
obj.foo();
4. new 키워드를 이용한 생성자 호출
new Foo();
5. call 또는 .apply 호출
foo.call(); foo.apply();
함수 실행에 따른 this 바인딩 패턴
패턴 바인딩되는 객체 설명 Method 호출 부모 객체 (실행 시점에 온점 왼쪽에 있는 객체) 하나의 객체에 값과 연관된 메소드를 묶어서 사용할 때 주로 사용함 new 키워드를 이용한 생성자 호출 새롭게 생성된 인스턴스 객체 객체 지향 프로그래밍에서 주로 사용함 .call 또는 .apply 호출 첫번째 인자로 전달된 객체 this 값을 특정할 때 사용하며, 특히 apply의 경우 배열의 엘리먼트를 풀어서 인자로 넘기고자 할 때 유용함 흔히 사용하지 않는 패턴(중요 X)
패턴 바인딩되는 객체(브라우저) 바인딩되는 객체 (node.js) Global window (strict mode에서는 undefined) module.exports Function 호출 window (strict mode에서는 undefined) global Method 호출
메소드 호출은 객체.메소드() 과 같이 객체 내에 메소드를 호출하는 방법을 의미
카운터를 구현한 예제(Singleton 패턴)
let counter = { value: 0, increase: function () { this.value++; // 메소드 호출을 할 경우, this는 counter를 가리킴 }, decrease: function () { this.value--; }, getValue: function () { return this.value; }, }; counter.increase(); counter.increase(); counter.increase(); counter.decrease(); counter.decrease(); counter.getValue(); // 1
function makeCounter() { return { value: 0, increase: function () { this.value++; // 메소드 호출을 할 경우, this는 makeCounter 함수가 리턴하는 익명의 객체 }, decrease: function () { this.value--; }, getValue: function () { return this.value; }, }; } let counter1 = makeCounter(); counter1.increase(); counter1.getValue(); // 1 let counter2 = makeCounter(); counter2.decrease(); counter2.decrease(); counter2.getValue(); // -2
생성자 호출
생성자 호출은객체.메소드() 과 같이 객체 내에 메소드를 호출하는 방법과 비슷하지만,
객체가 new 키워드를 이용해서 만들어졌다는 것이 다르다.이때의 객체를 인스턴스라고 부른다. 즉 인스턴스.메소드() 의 형태의 호출
class Counter { constructor() { this.value = 0; // 생성자 호출을 할 경우, this는 new 키워드로 생성한 Counter의 인스턴스 } increase() { this.value++; } decrease() { this.value--; } getValue() { return this.value; } } let counter = new Counter(); // 생성자 호출 counter.increase(); counter.increase(); counter.increase(); counter.decrease(); counter.getValue(); // 2
node.js 환경에서는 브라우저 환경의 window와 비슷하게 작동하는 global이라는 객체가 존재
함수 선언식 호출시 this 값
function foo() { return this; } foo(); // global
함수 표현식 호출시 this 값
const foo = function () { return this; }; foo(); // global
화살표 함수 호출시 this 값
const foo = () => { return this; }; foo(); // module.exports
화살표 함수
함수 표현식
const add = function (a, b) { return a + b; };
화살표 함수
const add = (a, b) => { return a + b; };
ES6에서 새로 도입한 화살표 함수(arrow function) 화살표 함수는 function 키워드를 화살표로 축약해서 표시할 수 있다.
함수의 본문(body)에 return 문만 있는 경우, 화살표 함수는 return을 생략할 수 있다.
이때 주의해야 할 점은 { } 중괄호(curly brace)는 사용하면 안 된다.( ) 소괄호(parentheses)를 사용하는 것은 가능
const add = (a, b) => a + b; // O, 정상 작동 const add = (a, b) => a + b; // O, 정상 작동 const add = (x, y) => { x + y; }; // X, undefined 리턴
화살표 함수는 클로저를 표현할 때 더욱 강력, 다음은 클로저의 한 예
const adder = (a) => { return (b) => { return a + b; }; };
가장 안쪽 return부터 생략. return 생략 시에는 중괄호를 사용하지 않는 점을 기억하자.
const adder = (a) => { return (b) => a + b; };
이제 하나 남은 return도 생략
const adder = (a) => (b) => a + b;
화살표 함수의 특징
- call, apply, bind를 사용할 수 없음
- 화살표 함수의 실행은 this를 결정짓지 않음
'Note' 카테고리의 다른 글
스택, 큐 (0) 2020.10.27 구조 분해 할당 (배열, 객체) (0) 2020.10.27 node.js와 관련 도구 (0) 2020.10.27 재귀함수 (0) 2020.10.27 고차함수, 콜백함수 (0) 2020.10.27