본문 바로가기
프론트엔드/[언어] 자바스크립트

[Lexical Scope] Static Scoping vs. Dynamic scoping

by 도툐리 2024. 3. 5.

JavaScript는 정적 스코핑(static scoping), 또는 **렉시컬 스코핑(lexical scoping)**을 사용합니다

 

이는 변수가 코드를 작성하는 시점에서의 범위에 따라 결정된다는 것을 의미합니다. 즉, 함수나 블록 내에서 변수를 참조할 때, JavaScript는 해당 변수가 코드 내에서 어디에 선언되었는지에 기반하여 변수의 범위를 결정합니다.

 

(In JavaScript, lexical scope is the concept of determining the scope of a variable based on its declaration. This means that the scope of a variable is determined by the block of code in which it is declared, not by the block of code in which it is used.)

 

var x = 'global';

function outer() {
    var x = 'outer';

    function inner() {
        // 여기에서 x를 참조하면 어디의 x를 참조하는가?
        console.log(x);
    }

    inner();
}

outer();
// 출력: 'outer'

 

위 예시에서 inner 함수 내부에서 x를 참조하면, JavaScript는 inner 함수의 바깥쪽으로 이동하면서 x 변수의 정의를 찾습니다.

 

이 경우, inner 함수는 outer 함수 내부에서 정의되었기 때문에, outer 함수 내에서 선언된 x ('outer')를 찾고, 그 값을 사용합니다. 이는 함수가 선언된 시점의 범위(렉시컬 환경)를 기준으로 변수를 해석하기 때문입니다.

 

반면에, **동적 스코핑(dynamic scoping)**을 사용하는 언어에서는, 함수가 실행되는 시점의 호출 스택에 따라 변수의 범위가 결정됩니다. 하지만 JavaScript는 이러한 방식을 사용하지 않습니다. JavaScript에서 함수의 실행 컨텍스트와 변수의 스코프는 함수가 작성된 위치에 의해 정적으로 결정됩니다.

 

-> 선언시점의 범위 vs 실행시점의 범위


동적 스코핑 예시

아래는 Perl 언어를 사용한 동적 스코핑의 예시입니다:

 

이 예시에서 동적 스코핑이 적용되는 부분은 dynamicScopeExample 함수 내부에서 local $x = 20;이라고 선언한 부분입니다. Perl에서 local 키워드는 변수에 대한 동적 스코핑을 생성합니다. 이것은 해당 변수의 값이 현재 실행 중인 함수 또는 블록 내에서만 임시적으로 변경되게 합니다.

 

dynamicScopeExample 함수가 실행될 때, $x 변수는 임시적으로 20의 값을 가집니다. 이 함수 내부에서 printX 함수를 호출하면, printX는 현재 활성화된 실행 컨텍스트 내에서 $x의 값을 찾습니다. 동적 스코핑 덕분에, 이때 printX는 전역 변수 $x의 원래 값을 참조하는 대신, dynamicScopeExample에서 임시로 설정된 20이라는 값을 찾아 출력합니다.

 

함수 호출이 끝나고 dynamicScopeExample의 실행이 완료되면, $x의 값은 원래의 전역 값인 10으로 복원됩니다. 그래서 마지막 printX 호출에서는 다시 10이 출력됩니다.

 

이 예시에서 동적 스코핑의 핵심은 변수 $x의 값이 함수의 호출 스택에 따라 결정된다는 것입니다. 즉, 변수의 값은 함수가 실행되는 시점의 컨텍스트에 따라 달라집니다. 이것이 바로 동적 스코핑이 정적 스코핑과 다른 점입니다.

 


 

\정적 스코핑(Static Scoping)과 동적 스코핑(Dynamic Scoping)은 프로그래밍 언어에서 변수의 범위(Scope)와 바인딩을 결정하는 두 가지 주요 방법입니다.

 

정적 스코핑(Static Scoping) 또는 렉시컬 스코핑(Lexical Scoping):

개념: 정적 스코핑에서는 변수의 스코프가 함수나 블록이 작성된 위치(코드의 텍스트 구조)에 의해 결정됩니다. 프로그램의 실행 경로와 무관하게, 코드를 작성하는 시점에서 변수의 범위가 정해집니다.

 

장점:

  1. 예측 가능성: 변수의 스코프가 코드를 작성하는 시점에 결정되므로, 프로그램의 동작을 더 쉽게 이해하고 예측할 수 있습니다.
  2. 유지보수성: 코드의 구조와 변수의 스코프가 명확하므로, 프로그램을 더 쉽게 유지보수할 수 있습니다.
  3. 버그 감소: 변수의 스코프가 명확하므로, 의도치 않은 스코프 내의 변수 변경을 줄일 수 있습니다.

단점:

  1. 유연성 부족: 특정 상황에서 코드의 재사용성이나 유연성이 제한될 수 있습니다.

 

동적 스코핑(Dynamic Scoping):

개념: 동적 스코핑에서는 함수나 블록의 실행 시점에 호출 스택을 기반으로 변수의 스코프가 결정됩니다. 즉, 변수는 해당 변수에 접근하는 코드가 실행되는 컨텍스트에 따라 다른 값을 가질 수 있습니다.

 

장점:

  1. 유연성: 함수나 변수를 다양한 실행 컨텍스트에서 재사용할 수 있어, 특정 상황에서 프로그램의 유연성을 증가시킵니다.
  2. 컨텍스트 기반 동작: 함수가 다른 환경에서 호출될 때 다르게 동작할 필요가 있는 경우, 동적 스코핑을 통해 이를 쉽게 구현할 수 있습니다.

단점:

  1. 예측하기 어려움: 변수의 값이 실행 컨텍스트에 따라 달라지기 때문에, 프로그램의 동작을 이해하고 예측하기 어렵습니다.
  2. 디버깅 어려움: 프로그램의 버그를 찾고 수정하기가 더 어려워질 수 있습니다, 특히 크고 복잡한 프로그램에서는 더욱 그렇습니다.
  3. 유지보수성 저하: 코드의 동작이 실행 컨텍스트에 따라 달라지므로, 프로그램의 유지보수가 더 어려워집니다.

대부분의 현대 프로그래밍 언어는 예측 가능성과 유지보수성을 중시하여 정적 스코핑을 사용합니다. 하지만, 특정 상황이나 특정 언어에서는 동적 스코핑이 유용할 수 있으므로, 각각의 접근 방식을 이해하는 것이 중요합니다.

 
 

 

In programming, scope determines the region within a program where a variable can be accessed. There are two primary types of scope mechanisms: static (or lexical) scoping and dynamic scoping.

 

When a variable is referenced in a dynamically scoped language, the language checks the call stack to resolve that reference, starting from the current function and moving outward until it finds a variable with the matching name or reaches the global scope.

 

In static scoping, the visibility of a variable is determined by its position in the source code. The variable's scope is fixed at compile time. This is the most common scoping mechanism in many modern languages.

 

 

Key Differences

Determining Variable Value:

  • Static: Based on its position in the source code.
  • Dynamic: Based on the calling function during runtime.

Common Usage:

  • Static: Found in languages like Java, Python, and C.
  • Dynamic: Predominantly in older languages or specific cases within languages like Lisp.

Predictability:

  • Static: More predictable since it depends on code structure.
  • Dynamic: Can be less predictable, depending on call sequences.

While static scoping is more prevalent and often deemed more intuitive, dynamic scoping offers unique flexibility in certain scenarios. Knowing the difference empowers developers to use each appropriately.

 


Javascript에서 Lexical Scoping을 사용하는 이유

  1. 예측 가능성과 이해의 용이성:
    정적 스코핑은 코드를 작성하는 시점에서 변수의 스코프가 결정됩니다. 이로 인해 개발자가 코드의 동작을 더 쉽게 예측하고 이해할 수 있게 됩니다. 변수가 선언된 위치를 기반으로 스코프가 결정되므로, 프로그램의 흐름을 따라가며 변수의 범위를 추적하는 것이 더 간단해집니다.

  2. 유지보수의 용이성:
    정적 스코핑은 코드의 구조가 더 명확하게 되므로, 프로그램의 유지보수가 더 용이해집니다. 개발자는 변수가 사용될 컨텍스트를 쉽게 파악할 수 있고, 이로 인해 코드의 디버깅과 수정이 더 쉬워집니다.

  3. 모듈성과 재사용성:
    정적 스코핑은 모듈화와 코드 재사용을 더 용이하게 만듭니다. 함수와 변수의 스코프가 명확하므로, 코드 조각을 다른 부분에 재사용할 때 예상치 못한 동작을 피할 수 있습니다.

  4. 함수형 프로그래밍의 지원:
    JavaScript는 함수형 프로그래밍 패러다임을 지원하는 언어입니다. 함수형 프로그래밍에서는 순수 함수와 불변성이 중요한 개념인데, 정적 스코핑은 이러한 패러다임과 잘 맞습니다. 정적 스코핑은 함수의 동작이 그 함수의 외부 스코프에 의존하지 않도록 함으로써, 순수 함수를 작성하기 더 쉽게 만듭니다.

  5. 일관성과 안정성:
    대부분의 현대 프로그래밍 언어는 정적 스코핑을 사용합니다. JavaScript가 이러한 표준을 따름으로써, 개발자들이 다른 언어와 비교했을 때 일관된 프로그래밍 경험을 가질 수 있게 됩니다.

Common Mistakes with Lexical Scope

There are a few common mistakes that people make when using lexical scope in JavaScript.

  • Declaring variables outside of functions: Variables should always be declared inside of functions, not outside of functions. This is because variables that are declared outside of functions are global variables, which can lead to problems.
  • Using the same variable name in multiple scopes: It is not allowed to use the same variable name in multiple scopes. If you try to do this, you will get an error.
  • Forgetting to declare variables: Variables must be declared before they can be used. If you try to use a variable that has not been declared, you will get an error.

 

 


참고

https://cleverzone.medium.com/lexical-scope-in-javascript-929789101dab

 

Lexical Scope in JavaScript

In JavaScript, lexical scope is the concept of determining the scope of a variable based on its declaration. This means that the scope of a…

cleverzone.medium.com

https://marketsplash.com/tutorials/lisp/lisp-dynamic-scoping/#link1

 

How To Understand Lisp Dynamic Scoping

Dynamic scoping is a distinctive feature in programming that alters the way variable bindings are resolved. While it contrasts with the more familiar static scoping, it has its merits. In this article, we'll delve into its mechanics, implications for devel

marketsplash.com

 

댓글