함수 선언

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]] 링크
  • 참고사이트
  • 참고사이트 prototype
function Person() {}
var joon = new Person();
var jisoo = new Person();
Person.prptotype.getType = function () {
  return "인간";
};

클로저

  • 전역변수를 줄일 수 있다. 전역변수가 많으면 어디에서든 실수로라도 접근을 할 수 있기 때문에 최대한 전역변수를 줄여서 코딩해야함.
  • 클로저는 내부에 선언된 함수가 외부함수의 지역변수를 사용해 줬을 때만 클로저라고 선언된다.
  • 함수에서 선언한 변수를 참조하는 내부함수를 외부로 전달할 경우, 함수의 실행 컨텍스트가 종료된 후에도 변수가 사라지지 않는 현상. 클로저 함수를 호출한 함수가 종료되었더라도 클로저 함수가 사용이 된다면 종료된 함수의 변수를 기억.
  • 내부함수를 외부로 전달하는 방법에는 함수를 return하거나 콜백으로 전달
  • 클로저는 그 본질이 메모리를 계속 차지하는 개념이므로 더는 사용하지 않게 된 클로저에 대해서는 메모리를 차지하지 않도록 관리 (fn = null; )
  • 실습파일 : 03_07_01_closure.html

closure

일반함수와 화살표 함수의 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");
});

Categories:

Updated: