파트 1 - 5) 함수 심화학습 - 2~4

Lee·2021년 12월 1일
0

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
  • 기존 문법으로는 arguments 문법이 있다.
    함수내에서 arguments를 사용하여(유사 배열 객체) 인덱스를 통해 모든 인수에 접근할 수 있다.
function showname () {
	alert( arguments.length );
}

유사배열 객체이기 때문에 배열 메서드는 사용할 수 없다. (ex. map)

  • 화살표 함수는 this가 없는 것처럼 arguments 도 없다.
    활살표 함수에서 arguments를 호출 하면 외부에 있는 '일반 함수'의 arguments를 가져온다.

3) 변수의 유효범위와 클로저 https://ko.javascript.info/closure
자바스크립트에서 실행중인 함수, 코드블록 {...}, 스크립트 전체는 '렉시컬 환경'이라는 '내부 숨김 연관 객체'를 갖는다.

  • 렉시컬 환경 객체
  1. 환경 레코드 : 모든 지역변수를 프로퍼티로 저장. this 같은 기타 정보도 여기에 저장된다.
  2. 외부 렉시컬 환경에 대한 참조 : 외부코드와 연관됨.
  • 변수는 '환경 레코드'의 프로퍼티. 즉, 변수를 가져오거나 변경하는 건 환경 레코드의 프로퍼티를 가져오거나 변경하는 것과 같다.
    ex) let phrase = "Hello"; 는 환경 레코드의 phrase라는 프로퍼티에 "Hello"라는 값을 저장한 것과 같다.

  • 스크립트 전체와 관련된 렉시컬 환경은 전역 레시컬 환경이라고 한다.

코드가 실행되고 실행 흐름이 이어지면서 렉시컬 환경이 변화한다.
변화 단계는
1. 스크립트가 시작되면 스크립트 내에서 선언한 변수 전체가 렉시컬 환경에 올라간다(pre-populated). 이때 변수는 uninitialized 상태가 된다. 자바스크립트 엔진은 uninitialized 상태의 변수를 인지는 하지만 let 을 만나기 전까진 이 변수를 참조(사용)할 수 없다.
2. let 까지 붙어서 선언되면 이 시점 이후부터 해당 변수를 사용할 수 있다.

  • 스크립트 내에서 함수 선언문으로 선언한 함수는 변수와 달리 스크립트가 시작되면 바로 초기화 되어 렉시컬 환경이 만들어지는 즉시 사용할 수 있다.
    즉, 변수(환경 레코드 프로퍼티)가 uninitialized 상태일 때 함수는 값이 function으로 초기화 되어 있다. (환경 레코드의 해당 함수 프로퍼티의 값이 function)

  • 코드에서 변수에 접근할 땐, 먼저 내부 렉시컬 환경에서 검색하고 내부 렉시컬 환경에서 원하는 변수를 찾지 못하면 검색 범위를 내부 렉시컬 환경이 참조하는 외부 렉시컬 환경으로 확장한다. 이 과정은 검색 범위가 전역 렉시컬 환경으로 확장될 때까지 반복됩니다.
    전역 렉시컬 환경에 도달할 때까지 변수를 못 찾으면 엄격 모드에서는 에러가 발생한다.
    (비 엄격모드에서는 하위호환을 위해 에러 발생이 되지 않고 새로운 전역변수를 생성한다)

클로저는 함수가 생성될 당시의 외부 변수를 기억하고 이 외부 변수에 접근할 수 있는 함수를 의미 (함수와 렉시컬 환경의 조합)

  • 자바스크립트 엔진은 변수 사용을 분석하고 외부 변수가 사용되지 않는다고 판단되면 이를 메모리에서 제거한다.
    디버깅 시, 최적화 과정에서 제거된 변수를 사용할 수 없다는 점은 V8 엔진(Chrome, Opera에서 쓰임)의 주요 부작용이다.
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
profile
하고 싶은 게 너무 많습니다.

0개의 댓글

관련 채용 정보