[JavaScript] scope

zwundzwzig·2022년 7월 24일
0

[javascript]

목록 보기
2/13
post-thumbnail

javascript 변수를 공부하며 scopeclosure를 접해 하는 정리
자바스크립트를 이해하기 위해선 클로저를 알아야하고, 클로저를 알기 위해선 스코프 개념 이해가 필요하다.

scope

자바스크립트에서 선언된 변수 or 함수의 유효 범위, 생존기간 등을 의미
모든 변수는 선언과 동시에 개인적인 scope를 갖는다.
계층적 특성을 가지며 하위 스코프는 상위 스코프에 접근할 수 있지만 반대는 불가하다.

지역 스코프 (Local scope / Function-level scope) : 정의된 함수 내에서 참조 가능
전역 스코프 (Global scope) : 코드 어디서든 참조 가능
↓
지역 변수 (Local variable) : 지역 scope를 갖는 변수
전역 변수 (Global variable) : 전역 scope를 갖는 변수

자바스크립트만의 유효범위 특징을 크게 분류하면 다음 네 가지이다.

  • 함수 단위의 유효 범위 (function-level scope)
  • 변수명 중복 허용
  • 암묵적 전역 (implied globals)
  • 어휘적 범위 지정 (Lexial scoping / Static scoping)

함수 단위의 유효 범위

대부분의 C-family language는 코드 블록({…})내에서만 유효한 블록 레벨 스코프(block-level scope)를 따른다.
javascript는 함수 코드 블록 내에서 선언된 변수는 함수 코드 블록 내에서만 유효한 function-level scope 이다.
단, ECMAScript 6에서 도입된 let keyword를 사용하면 블록 레벨 스코프도 사용 가능

var x = 'global';

function foo() {
  var x = 'local';
  console.log(x);
};

foo();          // local
console.log(x); // global

위 예제와 같이 변수명이 중복된 경우, 지역변수를 우선하여 참조한다.
함수 내에서 선언된 매개변수와 변수는 함수 외부에서는 유효하지 않다.

변수명 중복 허용

글로벌 영역에 변수를 선언하면 이 변수는 어느 곳에서든지 참조할 수 있는 global scope를 갖는 전역 변수가 된다.
var 키워드로 선언한 전역 변수는 전역 객체(Global Object) window의 property

function foo() {
  scope = 20;
  console.log("scope = " + scope);
};

function foooo() {
  console.log("scope = " + scope);
};

foo();   // scope=20
foooo(); // scope=20

위 코드처럼 함수 내에서 변수를 호출하면 전역 변수가 아닌 다른 함수 내에 있는 지역 변수를 참조한다.
전역 변수의 사용은 변수 이름이 중복될 수 있고, 의도치 않은 재할당에 의한 상태 변화로 코드를 예측하기 어렵게 만드므로 사용을 억제해야 한다.
코드가 길어지면 변수명의 중복이 발생하기 쉬워 예기치 못한 이상 동작의 원인이 되기 쉬우며, 전역변수는 지역변수보다 탐색에 더 오랜 시간이 걸린다.
전역변수를 반드시 사용할 이유가 없다면 지역변수를 사용해야 한다. 스코프는 좁을수록 좋기 때문이다.

암묵적 전역

var x = 10; // 전역 변수

function foo () {
  y = 10; // 선언하지 않은 식별자
  console.log(x + y);
}

foo(); // 20

위 코드에서 y는 선언하지 않은 식별자이기 때문에 에러가 발생할 것으로 보이지만,
자바스크립트 엔진에선 window.y = 10으로 해석해 전역 변수처럼 동작한다.
y는 변수 선언없이 전역 객체의 property로 추가된 것다. 변수가 아닌 y는 호이스팅되지 않는다.
y는 변수가 아니라 프로퍼티이기 때문에 delete 연산자로 삭제가 가능하다.

어휘적 범위 지정

함수와 변수가 호출이 아닌, 선언된 위치를 기준으로 스코프한다.

var x = 1;

function foo() {
  var x = 10;
  bar();
}

function bar() {
  console.log(x);
}

foo(); // 1
bar(); // 1

위 코드의 bar 함수는 선언된 위치에서 상위 스코프는 전역 스코프이다.
반대 개념으로 함수의 호출 위치를 기준으로 상위 스코프를 찾는 방식을 동적 스코프 (dynamic scope)라고 하며, 자바스크립트는 렉시컬 스코프를 따른다.
즉, 자신의 scope -> 자신이 선언된 외부 함수의 scope -> 전역 scope 순으로 변수를 찾아 호출한다. : 스코프 체인

스코프 체인

이렇게 계속 범위를 넓혀 상위 스코프를 찾는 개념
내부 함수에서는 외부 함수의 변수에 접근 가능하지만 외부 함수에서는 내부 함수의 변수에 접근할 수 없다.

var name = 'zero';

function outer() {
  console.log('외부', name);
  function inner() {
    var enemy = 'nero';
    console.log('내부', name);
  }
  inner();
}

outer(); //  외부 zero; 내부 zero;
console.log(enemy); // undefined

inner 함수는 name 변수를 자신의 scope, outer 함수 scope, 전역 scope 순으로 찾는다.

참조

profile
개발이란?

0개의 댓글