2) 나머지 매개변수와 전개문법 https://ko.javascript.info/rest-parameters-spread
function example (a, b, ...c) {
//logic
}
여기서 ...c 는 함수 호출 시 들어온 인수들 중 a, b를 제외한 나머지 인수를 담은 배열이다.
function example (a, b, ...c) {
alert(c)
}
example(1,2,3,4,5); //3,4,5
function showname () {
alert( arguments.length );
}
유사배열 객체이기 때문에 배열 메서드는 사용할 수 없다. (ex. map)
3) 변수의 유효범위와 클로저 https://ko.javascript.info/closure
자바스크립트에서 실행중인 함수, 코드블록 {...}, 스크립트 전체는 '렉시컬 환경'이라는 '내부 숨김 연관 객체'를 갖는다.
변수는 '환경 레코드'의 프로퍼티. 즉, 변수를 가져오거나 변경하는 건 환경 레코드의 프로퍼티를 가져오거나 변경하는 것과 같다.
ex) let phrase = "Hello"; 는 환경 레코드의 phrase라는 프로퍼티에 "Hello"라는 값을 저장한 것과 같다.
스크립트 전체와 관련된 렉시컬 환경은 전역 레시컬 환경이라고 한다.
코드가 실행되고 실행 흐름이 이어지면서 렉시컬 환경이 변화한다.
변화 단계는
1. 스크립트가 시작되면 스크립트 내에서 선언한 변수 전체가 렉시컬 환경에 올라간다(pre-populated). 이때 변수는 uninitialized 상태가 된다. 자바스크립트 엔진은 uninitialized 상태의 변수를 인지는 하지만 let 을 만나기 전까진 이 변수를 참조(사용)할 수 없다.
2. let 까지 붙어서 선언되면 이 시점 이후부터 해당 변수를 사용할 수 있다.
스크립트 내에서 함수 선언문으로 선언한 함수는 변수와 달리 스크립트가 시작되면 바로 초기화 되어 렉시컬 환경이 만들어지는 즉시 사용할 수 있다.
즉, 변수(환경 레코드 프로퍼티)가 uninitialized 상태일 때 함수는 값이 function으로 초기화 되어 있다. (환경 레코드의 해당 함수 프로퍼티의 값이 function)
코드에서 변수에 접근할 땐, 먼저 내부 렉시컬 환경에서 검색하고 내부 렉시컬 환경에서 원하는 변수를 찾지 못하면 검색 범위를 내부 렉시컬 환경이 참조하는 외부 렉시컬 환경으로 확장한다. 이 과정은 검색 범위가 전역 렉시컬 환경으로 확장될 때까지 반복됩니다.
전역 렉시컬 환경에 도달할 때까지 변수를 못 찾으면 엄격 모드에서는 에러가 발생한다.
(비 엄격모드에서는 하위호환을 위해 에러 발생이 되지 않고 새로운 전역변수를 생성한다)
클로저는 함수가 생성될 당시의 외부 변수를 기억하고 이 외부 변수에 접근할 수 있는 함수를 의미 (함수와 렉시컬 환경의 조합)
function f() {
let value = Math.random();
function g() {
debugger; // Uncaught ReferenceError: value is not defined가 출력
}
return g;
}
let g = f();
g();
이론상으로는 value에 접근할 수 있어야 하지만 최적화 대상이 되어서 이런 에러가 발생한다.
let value = "이름이 같은 다른 변수";
function f() {
let value = "가장 가까운 변수";
function g() {
debugger;
// 콘솔에 alert(value);를 입력하면 '이름이 같은 다른 변수'를 출력
}
return g;
}
let g = f();
g();
4) 오래된 'var'
1. var는 스코프가 없다. if문에 선언된 var 변수에 전역에서 접근 하기도 하고 그렇다.
2. var 선언은 함수가 시작될 때 처리되어 선언 전에도 호출할 수 있다.
3. 이렇게 나중에 선언된 것을 끌어올려 사용하는 것을 호이스팅이라고 하는데 호이스팅은 선언만 끌어올리고 할당은 끌어올리지 않는다.
4.
function SayHi () {
alert(phrase);
var phrase = "Hello";
}
SayHi(); //할당은 끌어올리지 않으므로 undefined