JavaScript의Scope과 타언어 scope 와의 차이

Posted by negabaro kim on Saturday, March 9, 2019 Tags: js   3 minute read

scope에 대해서 알아야하는 이유

변수와 매개변수의 접근성과 생존기간을 제어할 수 있음. JavaScript에 대한 깊은 이해를 하기 위해서는 클로저(Closure)에 대해 알아야 되며 이를 알기 위해서는 Scope 개념의이해가 필요함.

scope(유효범위)이란?

Scope를 직역하면 영역, 범위라는 뜻이지만 프로그램 언어에서의 유효범위는 어느 범위까지 참조하는지. 즉, 변수와 매개변수(parameter)의 접근성과 생존기간을 뜻한다.

#유효범위의 종류

javascript의 유효범위는 2종류가 있음 하나는 전역 유효범위(Global Scope), 또 하나는 지역 유효범위(Local Scope)

전역 유효범위는 스크립트 전체에서 참조되는 것을 의미하는데, 말 그대로 스크립트 내 어느 곳에서든 참조됨

지역 유효범위는 정의된 함수 안에서만 참조되는 것을 의미하며, 함수 밖에서는 참조하지 못함.

JavaScript의 유효범위는 타언어와 다름

JavaScript의 유효범위는 다른 언어의 유효범위와는 다르다. 다른 프로그래밍 언어에 익숙한 개발자들은 주의가 필요

JavaScript 유효범위의 특징

언급했듯 JavaScript의 유효범위는 다른 프로그래밍언어와 다른 개념을 갖는다.

JavaScript 유효범위만의 특징을 크게 분류하여 나열하면 다음과 같음.

  1. 함수 단위의 유효범위
  2. 변수명 중복 허용
  3. var 키워드의 생략
  4. 렉시컬 특성

1. 함수 단위의 유효범위

다른 프로그래밍 언어들은 유효범위의 단위가 블록 단위이기 때문에 if,for문 안에서 선언한 변수를 해당 블록 밖에서 사용할 수 없지만

javascript는 함수 단위의 유효범위여서 함수 안에만 있으면 같은 유효범위를 가짐

함수안이라면 블록이 몇천개라도 싸그리 무시하고 참조가능하다는 얘기

2. 변수명 중복 허용

JavaScript는 다른 프로그래밍 언어와는 달리 변수명이 중복되어도 에러나 나지않음. 단, 같은 변수명이 여러 개 있는 변수를 참조할 때 가장 가까운 범위의 변수를 참조함.

예제

var song = 'Signal';
function FamousSong() {
  var song = 'TT';
  if (true) {
    if(true) {
      var song = 'Yes or Yes';
    }
  }
  console.log("song:", song);
}
FamousSong();

//실행결과
/*
song: 'Yes or Yes'
*/

3. var 키워드의 생략

다른 프로그래밍 언어의 경우 변수를 선언할 때 int나 char와 같은 변수 형을 썼지만, JavaScript는 var 키워드를 사용함

또한 다른 프로그래밍 언어의 경우 변수를 선언할 때 변수형을 쓰지 않을 경우 에러가 나지만 JavaScript는 var 키워드가 생략이 가능함.

기억해야할것은 var 키워드를 빼먹고 변수를 선언할 경우 전역 변수로 선언된다는것

function twice() {
 cnt = 9;
 console.log("cnt = " + cnt);
}

function itzy() {
 console.log("cnt = " + cnt);
}
twice(); //cnt =9
itzy();  //cnt =9

위 예제를 보면 twice함수안에서 cnt변수에 9를 대입하고 itzy함수에서 cnt를 선언하지 않았는데 불구하고 twice함수에서 선언한 cnt값을 출력하는걸 알 수 있다.

4. 렉시컬 특성

렉시컬 특성이란 함수 실행 시 유효범위를 함수 실행 환경이 아닌 함수 정의 환경으로 참조하는 특성이다.

위의 좌측코드를 봤을 때 함수 twice에서 함수 itzy를 호출하면 실행이 됨. twice,itzy함수 모두 전역에서 생성된 함수여서 서로를 참조할 수 있는것.

twice함수에서 itzy를 실행하므로 itzy함수가 실행되었을때는 twice함수에서 정의한 변수가 참조가능할지도 모른다. 하지만 이 렉시컬 특성에 의해 함수 정의시 기준에 xx변수가 없으면 itzy함수에서 xx를 찾을 수 없으므로 에러가 발생한다

블록 스코프가 존재하지 않음?

Java의 경우 if,for등 {}의 블록안에서도 블록스코프가 존재하나 Javascript는 존재하지 않음?

Javascript에서 블록스코프를 사용하고 싶으면 with명령을 사용하거나 무명함수를 정의 정의해서 바로 실행하는 방법이

블록스코프와 같은효과를 내는게 가능 let을 사용해도 블록스코프가 만들어짐

let

let で変数を宣言すればブロックスコープになりますよ

정리

글로벌 변수는 프로그램 어디에서든 참조가 가능,로컬 변수는 정의한 함수안에서만 참조가능 로컬변수는 var이 있고 없고에 따라 scope가 변함/변수 선언시 var를 붙이자 호이스팅에 의한 혼란을 피하기 위해 함수안에서 가장윗행에 변수선언을 적자 로컬변수의 스코프, 仮引数もローカル変数のスコープだが、参照渡しの場合は関数外から参照するオブジェクトにも影響を与えるので気をつける。

http://tacamy.hatenablog.com/entry/2012/12/30/191125
http://www.nextree.co.kr/p7363/