다음 섹션으로 넘어가기 전에 기초를 탄탄히 다지는 수업이 진행되는 요즘이다
생소한 개념이라 어렵지만 자꾸 보다보면 친해질 거라고 믿는다 😅
내가 자바스크립트를 안 시간은 인생의 반의 반의 반도 안 되었는 걸...!
언어적 이해보다 몸으로 익히자!
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
내부 함수를 1개만 return하는 게 아닌, 여러 개의 내부 함수 return이 가능하다.
내부 함수의 return 문을 객체로 작성하여 data와 method를 같이 묶어서 다룰 수 있다.
함수 재사용성을 극대화하며, 함수 하나를 완전히 독립적인 부품 형태로 분리하는 모듈화가 가능해진다.
scope를 이용해 값을 안전하게 다룰 수 있다
scope를 이용해 변수의 접근 범위를 closure하는 게 핵심!
불필요한 전역 변수 사용을 줄여 side effect를 줄인다
지역 함수에 변수를 숨겨두고 쓸 수 있는 것이다
2015년 ECMA Script6에 출시된 문법
immutable
//
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} //뒤에서부터 앞으로 덮어쓰여진다
function rest(para1, para2, ...args) { //rest parameter 적용
return [para1, para2, args];
}
console.log(rest('first')); //전달인자 1개만 주어지면?
>['first', undefined, []]
// 주어지지 않은 element는 undefined 를, rest parameter은 빈 배열을 출력한다
arguments
객체return arguments;
참고할 자료
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/rest_parameters
: 배열을 분해한 후, 개별 값을 변수에 할당한다
할당 과정에서 필요하지 않은 일부 반환 값은 무시한다.
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)
을 사용한 구조 분해 할당
//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주가 되었다.'
condition ? expression : expression
조건문 ? 'true시 실행할 표현식' : 'false시 실행할 표현식'
false 외에도 null, NaN, 0, 빈 문자열, undefined 등 조건문에 대한 falsy 값을 사용할 수 있다.
--> 해당 falsy 값이 나올 시 실행할 표현식 작성
스코프 체이닝 이란...?
method 란...?
: 객체의 속성으로 정의된 함수
scope
: 범수의 유효 범위 (global / local)
함수는 위에서 아래로 흐른다 !!
실행하지 않으면 실행되지 않는다. 호출 없으면 무시하고 스킵!!
return이 없으면 호출은 가능해도 undefined를 반환한다.
문제풀 때 함수의 매개변수 유무랑 선언 키워드 유무 확인할 것...
답에 크나큰 영향을 준다
참고로 함수의 매개변수는 해당 scope의 지역 변수로 취급된다
같은 이름의 변수가 다른 scope에 있으면 동명이인이다. 같은 게 절대 아님! (이렇게 변수명 짓지 말 것...)
며칠 때 같은 말 반복중이지만... 선언 키워드 없이 선언하는 것은 전역 변수로 취급 된다. 전역 변수에서 가져오고, 전역 변수를 변경하는 일이다.