function
함수 선언
function myFunc(param) {
//실행영역
}
함수 표현식 : 함수 리터럴을 사용해서 변수에 함수를 할당
const myFunc = function (param) {
//실행영역
};
화살표 함수
- 파라미터가 1개이면 () 생략가능. 0개이거나 2개이상이면 반드시 표기
- { } 생략하면 return문도 생략가능.
- 콜백함수와 익명함수에도 사용
const myfunc = function (param) {
return 결과;
};
const myFunc = (param) => {
return 결과;
};
const myFunc = (param) => 결과;
함수 파라미터
- 파라미터 수와 함수 호출 시 넘겨주는 인자 개수가 일치하지 않아도 된다.
- 기본 파라미터 : 없는 파라미터는 ‘Undefined’로 전달되었으나 ES6에서 파라미터에 기본값 지정이 가능함.
const myFunc = function (a = 0, b = 0) {
//실행영역
};
myFunc(1); // b=0으로 초기화됨
- 나머지 파라미터(=가변파라미터) : …(점3개)으로 표시. 맨 마지막 위치에만 사용가능함.
const myFunc = function (a, b, ...args) {
// a,b는 필수파라미터. 나머지는 0개에서 n개까지 배열로 받음
//실행영역
};
- arguments : 함수 실행 시 함수로 전달된 인자들의 정보를 담고 있는 객체. 자동생성
커링 함수(=partial application)
- 한번에 인수를 하나만 받는 함수
- 함수를 단순하고 읽기 쉬운 여러 개의 나누어진 부분으로 만드는 기법
- n개의 파라미터를 n차 depth를 가진 함수로 분리
- 중간 단계까지만 실행한 결과를 변수로 받아 다음 파라미터를 다양하게 확장이 가능하다. 파라미터가 많을 경우 코드 재활용성을 극단적으로 높일 수 있다.
function orderSet(burger, beverage) {
console.log("세트 " + burger + "," + beverage);
}
function orderSet(burger) {
return function (beverage) {
console.log("세트 " + burger + "," + beverage);
};
}
let order = orderSet("치즈버그");
order("콜라");
order("커피");
orderSet("치즈버그")("우유");
const orderSet = (burger) => (beverage) => {
console.log("세트 " + burger + "," + beverage);
};
펼침(=확산) 연산자(spread operator)
- 배열과 객체를 복사하거나 합할때 사용 가능
var arr = [1, 2, 3];
var arr2 = [...arr, 4, 5]; // [1, 2, 3, 4, 5]
var obj1 = { name: "aa", age: 20 };
var obj2 = { name: "bb", addr: "dg" };
var obj3 = { ...obj1, ...obj2 }; // {name: 'bb', age: 20, addr: 'dg'} 키가 중복되면 덮어쓴다
나머지 연산자(rest operator)
- 함수 호출시 인자로 사용
let calc = function (x, y, z) {
console.log(x, y, z);
};
let calc2 = function (x, ...params) {
console.log(x, params);
};
calc(...arr);
calc2(...arr);
- 배열,객체 구조분해 할당(Destructuring assignment)
const [a, b, ...rest] = [10, 20, 30, 40, 50];
var o = { p: 42, q: true };
var { p, q } = o;
({ p, q } = o); //선언없는 할당. var { p, q } = o; 와 같음
고차함수(High-order function)
- 함수를 인자로 받거나 다른 함수를 반환하는 함수
- 배열의 reduce(), map() 등이 대표적인 고차함수
setInterval(() => {}, 1000);
변수의 scope와 스코프 체인
- var는 let과 달리 구문 단위의 스코프 구분이 없다
- 호이스팅 : 변수 선언이 맨위로 끌어욜려지기 때문에 전역변수로 처리 02_08_01_func_hoisting.html
- 함수안에 변수명을 중복선언하는 경우 가장 가까운 위치에 선언된 변수를 사용. 02_08_02_func_duplicate.html
- 호출한 함수를 역으로 따라 올라 가면서 변수를 찾고 최종적으로 전역변수를 찾게 된다. 02_08_03_func_scopechain.html
var a = 1;
var b = 5;
function outerFunc() {
function inndrFunc() {
a = b;
}
console.log(a);
a = 3;
b = 4;
innerFunc();
console.log(a);
var b = 2;
}
outerFunc();
생성자 함수
Prototype
- Prtotype은 모든 객체가 공유하고 있어서 한번만 만들어지지만 this에 넣은 것은 객체 만들때마다 생성(메모리 할당)
prototype chaining
: 객체에 존재하지 않는 프로퍼티를 접근하려 시도하면 해당 객체의 내무 [[Prototype]] 링크를 따라 다음 객체를 탐색하고 최상위 프로토타입인 Object.prototype에서 찾지 못하면 탐색이 종료된다.- Prototype 객체 : 함수를 정의하면 함수만 생성되는 것이 아니라 Prptotype object도 같이 생성이 된다. 기본속성으로 constructor와 proto를 가지고 있다
constructor
속성 : 생성자 함수__proto__
속성 : [[Prototype]] 링크로서 생성자 함수에 정의해두었던 prototype을 참조한다.
prototype
속성 : 생성자 함수에 정의한 모든 객체가 공유할 원형 [[Prototype]] 링크- 참고사이트
- 참고사이트
function Person() {}
var joon = new Person();
var jisoo = new Person();
Person.prptotype.getType = function () {
return "인간";
};
클로저
전역변수를 줄일 수 있다.
전역변수가 많으면 어디에서든 실수로라도 접근을 할 수 있기 때문에 최대한 전역변수를 줄여서 코딩해야함.- 클로저는 내부에 선언된 함수가 외부함수의 지역변수를 사용해 줬을 때만 클로저라고 선언된다.
- 함수에서 선언한 변수를 참조하는 내부함수를 외부로 전달할 경우, 함수의 실행 컨텍스트가 종료된 후에도 변수가 사라지지 않는 현상. 클로저 함수를 호출한 함수가 종료되었더라도 클로저 함수가 사용이 된다면
종료된 함수의 변수를 기억
. - 내부함수를 외부로 전달하는 방법에는 함수를 return하거나 콜백으로 전달
- 클로저는 그 본질이 메모리를 계속 차지하는 개념이므로 더는 사용하지 않게 된 클로저에 대해서는 메모리를 차지하지 않도록 관리 (fn = null; )
- 실습파일 : 03_07_01_closure.html
-
[참고: 코어자바스크립트 위키북스 p145] - hoisting 참고
- closuer 참고
일반함수와 화살표 함수의 this
- mdn 화살표함수
- https://velog.io/@nemo/화살표-함수-this-arguments
- https://velog.io/@fa0o00/JS-this2-일반함수와-화살표-함수의-this
일반함수의 this
- 일반적으로 함수의 this는 window 객체를 참조한다.
- 함수 호출, 메소드 호출, 생성자 함수로 호출되냐에 따라 동적으로 this가 바인딩
- 함수 호출 방식 : this => 전역객체
- 메소드 내부함수에서 this가 전역객체에 바인딩되는 문제는 메소드에서 this를 (비전역) 변수에 할당하여 해결할 수 있다.
- 생성자 함수 호출 : this -> instance
- 인라인 이벤트 핸들러 방식 : this -> 전역객체
- 이벤트 핸들러 프로퍼티 방식 : this -> event.currentTarget
- addEventListener 메소드 방식 : 콜백 함수로 호출이 되지만 이벤트 핸들러 내부의 this는 이벤트 리스너에 바인딩된 요소(currentTarget)를 가리킨다.
- 이벤트 핸들러 함수에서 this는 이벤트가 발생한 요소를 가리킨다.
- use strict를 사용한 엄격 모드에서는 window 객체 대신 undefiend로 설정된다.
- bind(), call(), apply() 메서드를 통해 this가 참조할 객체를 지정해줄 수 있다.
화살표 함수와 this
- 익명함수로 사용
- 메소드나 생성자 함수, addEventListener()의 콜백함수로 사용할 수 없음
- 화살표 함수에는 this라는 변수 자체가 존재하지 않기 때문에 그 상위환경에서의 this를 참조.
화살표 함수는 선언될 시점에서의 상위스코프가 this로 바인딩 - 매개변수와 화살표 사이에 줄 바꿈이 포함될 수 없습니다.
- 화살표 함수에는 자체 arguments 객체가 없습니다. 나머지 매개변수(…rest) 사용
const box = document.querySelector(".box");
box.addEventListener("click", function () {
// this -> box
this.classList.toggle("opening");
setTimeout(function () {
// this -> window
this.classList.toggle("opening");
}, 500);
});
// Uncaught TypeError: cannot read property "toggle" of undefined
const box = document.querySelector(".box");
box.addEventListener("click", function () {
// this -> box
this.classList.toggle("opening");
setTimeout(() => {
// this -> box
this.classList.toggle("opening");
}, 500);
});
화살표 함수 이벤트 핸들러
이벤트 핸들러를 화살표 함수로 사용하면 this는 이벤트가 발행한 요소가 아닌 window를 가리킨다.
const box = document.querySelector(".box");
box.addEventListener("click", () => {
// this -> window
this.classList.toggle("opening");
});