[JavaScript] 스코프

Yuhallo·2023년 1월 2일
0

JavaScript

목록 보기
2/9
post-thumbnail

🧡 스코프

스코프(Scope)는 '범위'를 의미합니다. 자바스크립트에서는 변수 접근 규칙에 따른 변수의 유효범위로 사용됩니다. 또는 식별자(변수)를 찾기 위한 규칙이라고도 합니다.

💚 주요 규칙

  • 변수에는 접근할 수 있는 범위가 존재합니다. 중괄호({ })에 의해 범위가 나누어지고 이 범위를 스코프라고 부릅니다. function을 제외하고 { }로 묶이는 부분을 블록 스코프라고 합니다.

  • 바깥 쪽 스코프에서 선언한 변수는 안 쪽 스코프에서 사용할 수 있지만 반대로 안 쪽에서 선언한 변수는 바깥 쪽 스코프에서는 사용할 수 없습니다.

    🎀 vs. 내부함수는 자신을 포함한 외부함수, 전역변수에 접근할 수 있습니다. 따라서 함수 내부에서 전역변수의 값도 변경할 수 있습니다.(화살표 방향이 바뀌었을 뿐 사실상 같은 내용 입니다.)

  • 스코프는 중첩이 가능합니다. 액자식 구성처럼 액자 속의 액자 속의 액자로 중첩할 수 있습니다.

스코프의 종류

전역 스코프(Global scope)

  • 가장 바깥 쪽의 스코프를 말하며, 전역 스코프에서 선언한 변수는 '전역 변수' 라고 부릅니다. 전역 변수는 코드 어디에서든지 참조할 수 있습니다.

지역 스코프(Local scope)

  • 전역 외의 다른 스코프를 말하며, 지역 스코프에서 선언한 변수는 '지역 변수' 라고 부릅니다. 그 지역과 하부 지역에서만 참조할 수 있습니다. 따라서 함수 내의 변수는 함수 외부에서는 유효하지 않습니다.
  • 지역 변수는 전역변수보다 더 높은 우선순위를 가집니다. 즉 전역변수와 지역변수가 중복으로 선언된 경우 지역변수를 우선하여 참조합니다.

💚 변수선언과 스코프

  • 스코프는 블록스코프(Block scope)와 함수스코프(function scope) 두 가지 종류가 있습니다.

함수스코프(Function scope)

  • function 키워드가 등장하는 함수선언식(혹은 함수표현식)은 함수 스코프를 만듭니다.

  • var을 이용한 변수선언은 블록스코프를 무시하고 함수스코프만 따릅니다. (다만 화살표 함수의 블록 스코프는 무시하지 않습니다) 즉 var이 함수 내에서 선언된 경우에만 함수를 빠져나오지 못하고, 다른 곳에서 선언이 되었다면 어디에서든 쓰일 수 있습니다.

  • var 선언은 함수스코프 최상단에 선언됩니다. 선언 키워드 없는 선언은 최고 스코프에 선언됩니다. 함수 내에서 선언 키워드 없는 선언은 함수 실행 전까지 선언 되지 않은 것으로 취급합니다.

블록스코프(Block scope)

  • 중괄호({ }) 기준으로 범위가 구분됩니다. 자바스크립트에서 변수를 선언하는 기호 중 let은 블록스코프 입니다.

  • 블록 스코프 안에서 정의된 변수는 블록 범위를 벗어나는 즉시 접근할 수 없습니다. 범위 밖에서 호출시 ReferenceError가 납니다.

  • 블록은 시각적으로 들여쓰기가 적용되면서 분명하게 구분됩니다.

  • var선언은 시각적으로 들여쓰기되는 규칙을 무시하므로 시각적으로 명확하지 않습니다. 따라서 예측가능한 코드작성을 위해 let키워드로 선언하는 것을 권장합니다. 또한 let키워드는 재선언을 방지합니다.

  • const키워드는 변하지 않는 값, 즉 상수(constant)를 정의할 때 이용합니다. 재할당이 불가능하고, 재할당할 경우 TypeError를 내므로, 의도하지 않은 값의 변경을 막을 수 있습니다.

🎀 렉시컬 스코프(Lexical scope)
어휘적인 범위 지정을 의미합니다. 함수의 상위 스코프를 결정하는 방식으로, 어디서 선언하였는 지에 따라 상위 스코프를 결정하는 것입니다. 대부분의 프로그래밍 언어는 렉시컬 스코프를 따릅니다.

🎀 vs. 동적 스코프(Dynamic scope)
함수를 어디서 호출하였는 지에 따라 상위 스코프를 결정하는 방식입니다.

변수선언시 주의할 점

  • 브라우저에는 window라는 객체가 존재합니다.브라우저 창을 의미하는 객체이지만, 별개로 전역 영역을 담고 있습니다. 함수선언식으로 함수를 선언하거나, var로 전역변수를 만들면 window객체에서도 찾을 수 있습니다.

    🎀 전역객체
    전역 범위(global scope)에 항상 존재하는 객체를 의미합니다. 언어 자체나 호스트 환경에 내장되어 있는 경우가 많습니다. 브라우저에선 window 객체가 있습니다. 전역 객체를 사용하면 어디서든 접근 가능한 변수를 만들 수 있습니다. window.함수()로 전역함수로 호출하면 내부적으로 window 객체를 사용해 호출됩니다.

  • 전역변수는 어디서든 접근이 가능합니다. 전역변수를 많이 만들면 내가 작성하지 않은 다른 함수와 로직이 포함될 때 같은 이름으로 선언된 전역변수에서 문제가 발생하게 됩니다(이름이 중복될 수 있기 때문입니다). 의도치 않은 재할당에 의한 상태 변화로 코드를 예측하기 어렵게 만듭니다. 이를 side effect라고 하고, 최소화 하는 것이 바람직합니다.

    🎀 스코프 오염(Scope Pollution)
    전역 네임스페이스에 너무 많은 전역변수가 존재하거나, 다른 범위에서 변수를 재사용하는 상황을 말합니다. 즉, 선언된 변수가 너무 다양해서 기억하고 추적하기 어려워 다른 로컬 변수와 충돌하는 등의 다양한 오류를 만들어 냅니다.

  • 전역변수를 var로 선언하는 것은 브라우저의 내장 기능을 사용하지 못하게 만들 수도 있습니다. 또한 선언 없이 변수를 할당하면, 해당 변수는 var로 선언한 전역변수처럼 취급됩니다. 두 경우 모두 바람직 하지 않습니다.

바람직한 변수선언

  • strict Mode는 브라우저가 엄격하게 작동하도록 만들어 위의 위험을 방지해줍니다. 선언 없는 변수를 할당할 경우 Strict Mode는 에러로 판단합니다.js파일 상단에 'use strict'라고 입력하면 Strict Mode가 작동합니다.

  • 블록 스코프를 잘 사용해, 변수의 사용범위를 엄격하게 제한하여 스코프 오염을 방지해야 합니다. 이 경우 다양한 이점이 있습니다.

    • 블록이 코드를 개별 섹션으로 구분(들여쓰기)해 주어 가독성이 높아집니다.
    • 해당 변수가 다른 부분과 어떻게 연관되어 있는 지 따로 추적할 필요가 없어 코드를 이해하기 쉽습니다.
    • 코드가 모듈식으로 구성되어 유지 관리가 쉽습니다.
    • 로컬 변수들은 블록 실행이 완료된 후 사라지므로 메모리가 절약됩니다.

🧡 이해높이기

  • 함수 get은 x를 반환합니다. 이때 첫번째 코드에서 x는 전역스코프의 x를 가리킵니다. get함수 스코프 내에 x라는 변수가 별도로 선언되어 있지 않기 때문입니다. (get(20)의 20은 사용되지 않는 값입니다. 함수에 전달되어도 내부 어떤 변수에도 할당되지 않습니다.) 두번째 코드에서 x는 get함수 스코프에 선언된 매개변수 x입니다. get함수 전달인자 20이 x에 할당됩니다.

  • 코드에서 get함수의 x와 set함수의 x는 다릅니다. get함수의 x는 전역에 있는 변수 x지만, set함수의 x는 set함수 스코프 내에서 별도로 선언된 변수입니다. set(10)이 실행해도 전역x값에 영향을 주지 않습니다.
    set함수는 매개변수 value를 통해 전달받은 값을 전역 변수 x에 할당합니다. set(10)이 실행되면 전역변수 x는 10이 됩니다.(get(20)의 20은 함수 내부에서 사용되지 않아 영향을 미치지 않습니다.)
    코드 get함수는 매개변수 x를 통해 전달된 값을 반환하므로, get(20)은 20을 반환합니다. set(10)이 실행되면 전역변수 x의 값이 10으로 변경됩니다.
  • outer함수는 inner함수는 x를 반환합니다. inner함수 스코프 내에는 x 변수가 없고 outer함수 스코프 내 x가 선언되어 있어, outer함수 스코프에의 x가 inner함수 반환값이 됩니다.
    result에 할당된 x값은 전역스코프의 x입니다. 함수가 호출되어도 아무런 영향을 받지 않습니다. (덧, inner함수는 x값에 10을 더한 값을 반환합니다. inner에 의해 값이 변경되는 x는 outer스코프에 속한 x입니다. inner함수가 실행되면 outer함수의 변수 x는 30이 됩니다.)
    outer 함수는 전역변수 x에 20을 재할당합니다. result 값은 20이 됩니다. (inner는 함수 내에서 x를 선언했으므로 바깥 스코프에 영향을 미치지 않습니다.)
    outer, inner함수 모두 전역변수 x의 값을 변경합니다. outer함수로 x가 20이되고, 이어 inner함수가 호출되면서 다시 20이 더해져 40이 됩니다.


profile
개발자가 되고 싶어 둥당둥당

0개의 댓글