Javascript 핵심 개념과 주요 문법 - 2 클로저 / spread, rest

young·2022년 5월 16일
0

4/25~ 5/23 Section 1 TIL

목록 보기
15/23

다음 섹션으로 넘어가기 전에 기초를 탄탄히 다지는 수업이 진행되는 요즘이다
생소한 개념이라 어렵지만 자꾸 보다보면 친해질 거라고 믿는다 😅
내가 자바스크립트를 안 시간은 인생의 반의 반의 반도 안 되었는 걸...!

언어적 이해보다 몸으로 익히자!

1. 오늘 공부한 것

✅ 클로저 Closure 

: 외부 함수의 변수에 접근할 수 있는 내부 함수

return 하는 함수에 의해 scope가 구분된다 (외부 함수 / 내부함수)
단순히 함수 안의 함수라고 해서 closure인 게 아니라,
내부 함수에서 외부 함수의 변수에 접근하고 있어야 closure이라고 할 수 있다.

closure의 뜻은 '폐쇄'로
함수를 return 하는 함수이자
함수와 함수가 선언된 어휘적 환경(lexical environmnet)의 조합이다.

말이 어렵다..!

함수가 선언 될 때의 맥락(=어휘적 환경)을 기억하는 함수
라고 이해하면 될 것 같다


const adder = function(x) { // 외부함수, 변수 y에 접근 불가능
  return function(y) { // 내부함수
    return x + y;	// 외부함수의 변수 x에 접근하는 closure
  }
}

adder(1)(2);	// 실행
>3


이때 typeof adder(1) === 'function'이 된다 
내부함수를 return 하고 있기 때문이다

어휘적 환경을 메모리에 저장하고 있기 때문에
외부함수의 실행이 끝나더라도 외부함수의 변수를 계속 사용할 수 있다.

const add1 = adder(1); //function을 변수에 할당

add1(5) //--->adder(1)(5)
>6
  • 모듈화에 유리한 closure

    내부 함수를 1개만 return하는 게 아닌, 여러 개의 내부 함수 return이 가능하다.
    내부 함수의 return 문을 객체로 작성하여 data와 method를 같이 묶어서 다룰 수 있다.
    함수 재사용성을 극대화하며, 함수 하나를 완전히 독립적인 부품 형태로 분리하는 모듈화가 가능해진다.

  • 정보의 접근 제한 (캡슐화)

    scope를 이용해 값을 안전하게 다룰 수 있다
    scope를 이용해 변수의 접근 범위를 closure하는 게 핵심!
    불필요한 전역 변수 사용을 줄여 side effect를 줄인다
    지역 함수에 변수를 숨겨두고 쓸 수 있는 것이다



✅ spread / rest

2015년 ECMA Script6에 출시된 문법
immutable

  • spread syntax 전개 문법
    : 배열을 풀어서 인자로 전달하거나, 배열을 풀어서 각각의 요소를 전달할 때 사용한다.
    빈 배열을 spread로 전달할 경우, 아무것도 전달되지 않는다.
    여러 개의 배열을 이어 붙이거나, 여러 개의 객체를 병합할 수 있다.
    (뒤에서부터 앞으로 덮어쓰여진다)
//
const spread = ['o', 'u', 'n'];
const arr = ['y', ...spread, 'g']; //array spread의 element를 풀어서 전달

console.log(arr);
>['y','o','u','n','g']


//
const num1 = [1,2];
const str1 = ['a','b'];
const numstr = [...num1, ...str1]; //여러 개의 배열을 이어 붙일 때 사용

console.log(numstr);
>[1, 2, 'a', 'b']


//
const person = {
  name : 'young',
  age : 10
};
const velog = {
  name : 'y0ungg',
  today : 20,
  page : 2
};
const hello = {
  ...person,
  ...velog		//새로운 객체 hello에 person과 velog 병합하여 할당
};

console.log(hello);
>{name: 'y0ungg', age: 10, today: 20, page: 2}	//뒤에서부터 앞으로 덮어쓰여진다
  
  • rest parameter
    : 함수의 매개변수를 배열로 다룰 수 있게 한다.
    parameter의 개수가 가변적일 때 사용한다.
    항상 배열로 출력한다❗️
function rest(para1, para2, ...args) {	 //rest parameter 적용
  return [para1, para2, args];	
}

console.log(rest('first'));		//전달인자 1개만 주어지면?
>['first', undefined, []]
// 주어지지 않은 element는 undefined 를, rest parameter은 빈 배열을 출력한다
  • arguments 객체
    spread 도입 이전, 비슷하게 함수의 '전달인자'들을 다루었다
    모든 함수의 실행 시 자동으로 생성되는 객체이다
    배열 아님❗️
return arguments;

참고할 자료
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/rest_parameters



✅ 구조 분해 할당 (Destructing Assignment)

: 배열을 분해한 후, 개별 값을 변수에 할당한다
할당 과정에서 필요하지 않은 일부 반환 값은 무시한다.

const array = [123, 'b', [5,6]];
const [first, second] = array;
//변수 first와 second에 순서대로 index 0, 1의 element가 할당된다

console.log(first);
>123
console.log(second);
>'b'
  • spread syntax를 사용한 구조 분해 할당

    프로필 관리를 생각하니까 훨씬 쉽게 이해 된다

//1
const array = [123, 'b', 'young'];
const [first, ...rest] = array;

console.log(rest);
>['b', 'young']


//2
const user = {
  id : 'nunu',
  level : 51,
  tier : 'master'
}
const char1 = {
  ...user,
  skill : 'fire'
}
const char2 = {
  ...user,
  tier : 'grandMaster',
  skill : 'wind'
}

console.log(char1);
>{id: 'nunu', level: 51, tier: 'master', skill: 'fire'}

console.log(char2);
>{id: 'nunu', level: 51, tier: 'grandMaster', skill: 'wind'}

  • 💡객체의 단축 문법(shorthand)을 사용한 구조 분해 할당
    : 이미 정의되었던 변수의 값을 그대로 사용할 때,
    객체 리터럴에서 property의 이름을 같게 하여 할당을 생략할 수 있다.
//1
const name = 'young'
const age = 60

const person = {
  name,	
  age,	 //shorthand❗️
  height: 180,
}

console.log(person);
>{name: 'young', age: 60, height: 180}


//2
const whoRU = {
  name : 'frog',
  job : 'baker'
}
const {name} = whoRU;	 //shorthand❗️

console.log(name);
>'frog'


//3
const student = {
  name: 'young',
  major: '프론트엔드',
  week: 3,
  level: 1
}

function bootcamp({ name, major: course, week}) {
  return `${name}${course}를 수강한지 ${week}주가 되었다.`		//shorthand❗️
}
console.log(bootcamp(student));
>'young은 프론트엔드를 수강한지 3주가 되었다.'


2. 추가적으로 공부한 것

  • 삼항 조건 연산자 condition ? expression : expression
    : 세 개의 피연산자를 취하는 유일한 연산자
조건문 ? 'true시 실행할 표현식' : 'false시 실행할 표현식'

false 외에도 null, NaN, 0, 빈 문자열, undefined 등 조건문에 대한 falsy 값을 사용할 수 있다.
--> 해당 falsy 값이 나올 시 실행할 표현식 작성


3. 더 공부하자

  • 스코프 체이닝 이란...?

  • method 란...?
    : 객체의 속성으로 정의된 함수



4. 기억하자

  • scope : 범수의 유효 범위 (global / local)

  • 함수는 위에서 아래로 흐른다 !!
    실행하지 않으면 실행되지 않는다. 호출 없으면 무시하고 스킵!!
    return이 없으면 호출은 가능해도 undefined를 반환한다.

  • 문제풀 때 함수의 매개변수 유무랑 선언 키워드 유무 확인할 것...
    답에 크나큰 영향을 준다
    참고로 함수의 매개변수는 해당 scope의 지역 변수로 취급된다

  • 같은 이름의 변수가 다른 scope에 있으면 동명이인이다. 같은 게 절대 아님! (이렇게 변수명 짓지 말 것...)

  • 며칠 때 같은 말 반복중이지만... 선언 키워드 없이 선언하는 것은 전역 변수로 취급 된다. 전역 변수에서 가져오고, 전역 변수를 변경하는 일이다.

profile
즐겁게 공부하고 꾸준히 기록하는 나의 프론트엔드 공부일지

0개의 댓글