[자바스크립트 중고급] 3. 스코프(Scope)

Speedwell🍀·2022년 1월 26일
0

스코프 목적

  • 범위를 제한하여 식별자를 해결하려는 것
    • 스코프에서 식별자를 해결
  • 식별자 해결(Identifier Resolution)
    • 변수 이름, 함수 이름을 찾는 것
    • 이때 스코프를 사용
    • 이름을 찾게 되면 값을 구할 수 있음
    • 크게는 이름을 설정하는 것도 식별자 해결
  • 스코프는 식별자 해결을 위한 것

스코프 설정

function book(){
  var point = 123;
  function get(){
    log(point);
  };
  get();
};
book();

// 123
  1. 엔진이 funciton book(){}을 만나면

  2. function 오브젝트를 생성하고

  3. 스코프를 설정

    • 생성한 function 오브젝트의 [[Scope]]에 스코프를 설정
    • 즉, 이때 스코프가 결정됨
  4. JS의 스코프 설정 메커니즘

  5. 마지막 줄에서 book() 함수를 호출

  6. 엔진 컨트롤이 book 함수 안으로 이동

  7. function get(){}을 만나게 되며 function 오브젝트를 생성함

  8. 스코프를 설정

    • function 오브젝트으 [[Scope]]에 스코프를 설정
    • 이때 스코프가 결정됨
  9. get() 함수 호출


Global 오브젝트

var value = 100;
function book(){
  var point = 200;
  return value;
};
book();
  • var value = 100;
    • 100을 vlaue 변수에 할당하는 것은 value로 검색하여 값을 사용하기 위한 것
  • 함수 안에 변수를 선언하면 변수가 함수에 속하게 되지만, value 변수를 함수 안에 작성하지 않음
    • value 변수가 속하는 오브젝트가 없으며
    • 이때, 글로벌 오브젝트가 설정됨
  • 이런 매커니즘을 구현할 수 있는 것은
    • 글로벌 오브젝트가 하나만 있기 때문

Global 오브젝트 특징

// <script src-"./abc.js">
var value = 100;
function book(){
  return value + 50;
};
// <script src="./def.js">
log(value);
log(book());

// 100
// 150
  • JS 소스 파일 전체에서
    • 글로벌 오브젝트는 하나만 있음
    • new 연산자로 인스턴스 생성 불가
  • JS 소스 파일 전체 기준
    • <script>에 작성된 모든 코드
    • 모든 코드에서 사용 가능
  • def.js 파일의 코드에서
    • 글로벌 오브젝트에 작성된 변수 value 값을 출력하고 book() 함수를 호출

Global 스코프

  • 글로벌 오브젝트가 글로벌 스코프

  • 오브젝트는 개발자 관점으로

    • 오브젝트에 함수와 변수를 작성
  • 스코프는

    • 식별자 해결을 위한 것으로
    • 엔진 관점
  • 글로벌 스코프는 최상위 스코프

    • 함수에서 보면 최종 스코프
var value = 100;
function book(){
  return value;
};
book();
  • function book(){코드}에서

    • book 함수가 속한 오브젝트가 없으므로
    • book 함수가 글로벌 오브젝트에 설정
    • 글로벌 함수
  • var value = 100;

    • value 변수가 글로벌 오브젝트에 설정
    • 글로벌 변수
  • 글로벌 오브젝트에 설정된다는 것은 오브젝트 관점

  • 스코프와 식별자 해결 관점은

    • Scope가 글로벌 스코프라는 것
  • book();

    • book 함수를 호출하려면
    • "오브젝트.book()" 형태로 작성해야 하는데
    • 오브젝트를 작성하지 않고 함수만 작성
  • 오브젝트를 작성하지 않으면

    • 글로벌 오브젝트를 "오브젝트"로 간주하여
    • 글로벌 오브젝트의 book() 함수를 호출
  • 즉, 글로벌 스코프에서 book을 찾아 호출


바인딩

  • 구조적으로 결속된 상태로 만드는 것
    • 대상: 프로퍼티 이름
  • 바인딩 목적
    • 스코프 설정, 식별자 해결
  • 바인딩 시점 구분
    • 정적 바인딩(Lexical, Static Binding)
    • 동적 바인딩(Dynamic Binding)

정적, 동적 바인딩

  • 정적(렉시컬) 바인딩

    • 초기화 단계에서 바인딩
    • 함수 선언문 이름을 바인딩
    • 표현식(변수, 함수) 이름을 바인딩
  • JS는 대부분 정적 바인딩

  • 동적(다이나믹 바인딩)

    • 실행할 때 바인딩
    • eval() 함수, with 문

바인딩 시점의 중요성

  • 바인딩 시점이 중요한 이유

    • 바인딩할 때 스코프가 결정되기 때문
  • function 오브젝트 생성 시점에 스코프 결정

    • 스코프를 function 오브젝트의 [[Scope]]에 설정
    • 스코프가 변경되지 않음
  • 함수 안의 모든 함수의 스코프가 같음

function book(){
  var point = 100;
  function add() {point += 200;};
  function get() {return point;};
};

스코프 바인딩

function book(){
  var point = 100;
  function add(param){
    point += param;
  };
  var get = function(){
    return point;
  };
  add(200);
  log(get());
};
book();

// 300
  1. 마지막 줄에서 book() 함수 호출

    • 초기화 단계에서 함수와 변수 이름을
    • 선언적 환경 레코드에 바인딩
      ➡️ 앞으로 레코드라고 부르겠음
  2. function add(param){...}

    • function 오브젝트 생성
    • add 함수가 속한 스코프(영역)를 add 오브젝트의 [[Scope]]에 설정
    • add 이름을 레코드에 바인딩
  3. var point = 100;

    • point 이름을 레코드에 바인딩
  4. var get = function(){...}

    • get 이름을 레코드에 바인딩
  5. 바인딩으로 함수와 변수의 식별자로 해결됨

========= 코드 실행 ===========

  1. var point = 100;

    • point 변수에 100 할당
  2. var get = function(){...}

    • function 오브젝트 생성, get에 할당
    • get 함수가 속한 스코프(영역)를 get 오브젝트의 [[Scope]]에 설정

========= add() 함수 호출 ==========

  1. add(200) 함수를 호출

  2. point += param;

    • 먼저 레코드에서 point 이름을 찾음
    • point가 없으므로 다시 검색하게 되며
    • add 오브젝트의 [[Scope]]를 스코프로 사용
    • book 오브젝트가 스코프이며 point가 있으므로 값을 더함

========== get() 함수 호출 ==========

  1. get() 함수 호출

  2. return point;

    • 레코드에 point가 없으므로 다시 검색
    • get 오브젝트의 [[Scope]]를 스코프로 사용
    • book 오브젝트가 스코프이며 point가 있으므로 값을 반환

동적 바인딩

  • 코드를 실행할 때마다 바인딩

    • with 문
    • eval() 함수
  • with 문

    • "use strict" 환경에서 에러 발생
  • eval() 함수

    • 보안에 문제 있음

0개의 댓글