JS에서 함수는 함수 외부 변수를 참조할 수 있음. 이걸 '변수를 capture한다'고 표현
let z = 100;
function addToZ(x, y) {
return x + y + z;
}
function add(x: number, y: number): number {
return x + y;
}
let myAdd = function(x: number, y: number): number { return x + y };
캡처된 변수는 타입에 반영되지 않음.
함수의 매개변수와 반환값에 타입을 주는 게 아니라 함수 자체에 타입 적용
let myAdd: (x: number, y: number) => number =
function(x: number, y: number): number { return x + y; };
TS 컴파일러는 타입을 추론한다. 이런걸 contextual typing라고 함.
// 옵셔널 지정
function buildName(firstName: string, lastName?: string)
// 기본값 지정
// 이건 매개변수가 undefiend일 때도 해당
function buildName(firstName: string, lastName = "Smith")
function buildName(firstName: string, ...resfOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
나머지 매개변수는 선택적 매개변수들의 수를 무한으로 취급
this는 함수가 호출될 때 정해지는 변수
즉, 함수가 실행되는 콘텍스트를 알아야 this를 알 수 있다.
최상위 레벨에서 비-메서드(함수) 호출의 경우 this는 window
(단, strict mode에서는 undefiend)
화살표 함수의 this는 호출된 곳이 아닌 함수가 생성된 쪽의 this를 캡처한다.
class Counter {
constructor() {
this.count = 0;
}
start() {
setInterval(() => {
this.count++;
console.log(this.count);
}, 1000);
}
}
const myCounter = new Counter();
myCounter.start();
function showCount() {
console.log(this.count);
}
const obj = {
count: 5,
showCount: showCount
};
obj.showCount(); // 5
showCount(); // undefined 또는 브라우저 환경에서는 window.count
const obj = {
count: 5,
showCount: function() {
setTimeout(() => {
console.log(this.count);
}, 1000);
}
};
obj.showCount(); // 5, 화살표 함수는 showCount가 호출된 obj의 this를 상속받음
화살표 함수는 함수로 호출되더라도, 함수가 생성된 컨텍스트의 this에 바인딩된다.
즉, 화살표 함수가 정의될 때 주변 스코프의 this 값을 캡처하는 것
만약, setTinterval같은 비동기 함수에서 전통적인 함수를 콜백으로 쓰면 그 함수의 this는 전역 객체(엄격모드에서는 undefiend)를 가리키게 된다.
인스턴스 내부에서 this를 올바르게 참조하려면 화살표 함수를 써야 함.
일반 함수의 this는 정의가 아니라 호출될 때 결정된다는 것 기억하기
화살표 함수의 this 바인딩은 함수가 선언된 시점의 this를 캡처한다.
같은 이름의 함수를 다른 매개변수 타입이나, 매개변수 개수에 따라 다르게 정의
자바스크립트는 동적인 언어이므로, 인자에 따라 다른 타입의 객체를 반환하는 건 흔하다.
그래서 이렇게 다르게 함수를 선언할 수 있음.
// 이거 2개가 오버로드 목록
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x: any): any {
// 여기서 x의 타입에 따라 분기 처리를 하여 각 오버로드에 맞는 로직을 수행
if (typeof x == "object") {
// 첫 번째 오버로드에 해당하는 로직
let pickedCard = Math.floor(Math.random() * x.length);
return pickedCard;
}
else if (typeof x == "number") {
// 두 번째 오버로드에 해당하는 로직
let pickedSuit = Math.floor(x / 13);
return { suit: suits[pickedSuit], card: x % 13 };
}
}
컴파일러는 오버로드 목록에서 첫 번째 선언으로 함수 호출 시도, 이후 순차적
따라서 구체적인 것부터 오버로드 리스팅하는 것이 일반적