JS : Scope

?·2020년 9월 18일
0

TIL

목록 보기
1/2

이전에 hoisiting에 대해서 공부를 하며 scope를 잠시 언급한 적이 있다.

java script에서 scope란 '변수가 어디까지 쓰일 수 있는지'의 범위를 의미한다.

'something' is not defined 라는 문구를 만났을 때 ' 아닌데? 난 이미 변수를 선언했는데?' 라고 생각한다면,
변수를 선언한 영역에 접근할 수가 없어 컴퓨터가 변수가 선언되었다는 사실을 알지 못해서 그랬을것 이다.

어떠한 변수는 여기저기서 쓸 수 있는 반면에 어떤 변수는 정해진 범위 내에서만 사용이 가능하다. 바로 이러한 개념이 scope이다.

scope에 대해서 자세히 알아보기에 앞서 block 개념을 명확하게 할 필요가 있다.

block이란 {중괄호}로 감싸진 것을 의미한다.

따라서 function의 내부는 하나의 block이다.

 function example () {
   return "block";
 }

그리고 for문 역시 하나의 block이다.

for (let i =o; i < 10; i++) {
}

if문 역시 마찬가지이다.

{}(block)내부에서 변수가 정의되면 변수는 오로지 {}(block)내부에서만 사용할 수 있다.
그리고 {}(block)내부에서 정의된 변수는 local(지역) 변수라고 부릅니다.

지역변수의 개념을 잘 모른다면 흔하게 할 수 있는 실수는 다음과 같다.

function getresult (){
   let result = 10;
   return result;
 }

console.log(result);

위와 같은 코드를 친다면, 'ㅇㅇ라너ㅣ;민'라는 오류 메세지를 볼 수 있다. 변수 result 는 함수(블록)안에서 선언되었기 때문에 함수 밖에 있는 console.log(result)에서는 result라는 변수에 접근 할 수 없는 것이다.

지역변수는 블록이 끝나면 더 이상 변수가 살아있지 않고, 쓸 수 없다.




반면에, 코드 어디에서 접근이 가능한 변수가 있다. 이것을 전역변수라 한다.

전역변수는 {block} 밖에서 만들어지며, 코드의 어디서든 접근이 가능하다.

 const color = 'red';
console.log(color);

function returnColor() {
  console.log(color);
  return color;
}

console.log(returnColor());

returnColor 함수 내에서, returnColor 함수 밖에 있는 color라는 변수를 return 해주었다.

color라는 변수는 global(전역) 변수이기 때문에 returnColor함수의 block에서도 접근이 가능해서 'red'를 반환한 것이다.




global 변수를 쓰면 여기 저기서 접근하기 쉬워서 좋다고 생각할 수 있지만, 너무 남용하면 문제를 일으킬 수 있다. Scope의 오염을 일으킬 수 있기 때문이다.

코드에 흙탕물 뿌리기도 아니고 어떻게 scope가 오염된다는 것일까?

global 변수는 프로그램이 종료될 때까지 계속 살아있다. 그렇기 때문에 변수가 계속 살아있어서 코드 안에서 변수값이 계속 변한다면 해당 변수를 트래킹하기도 어렵고 이 변수는 어디에서 왜 필요한지 알려면 도대체 어디에서 let, const로 선언을 했는지 찾아 나서야 한다.

다음은 대표적인 scope 오염의 예이다.

const satellite = 'The Moon';
const galaxy = 'The Milky Way';
let stars = 'North Star';

const callMyNightSky = () => {
stars = 'Sirius'; // let으로 새로 선언하지 않았기 때문에 전역변수 stars에 영향을 미치게 된다. 

return 'Night Sky: ' + satellite + ', ' + stars + ', ' + galaxy;
};

console.log(callMyNightSky());
console.log(stars);

위와 같은 상황에서는 다른 함수에서 global 변수인 stars을 사용하고 싶어도 값이 수정된 "Sirius"으로 사용하게 되는 것이다.

따라서 좋은 Scope 습관이란!

global 변수는 쓰지 않도록 노력해야 하고,
최대한 {} 내에서 let, const을 사용하여 변수를 새로 만들어서 쓰도록 해야한다.

타이트한 scope(tightly scoping)의 변수는 코드 품질을 올려줍니다!!
코드가 block으로 명확하게 구분되기 때문에 코드 가독성이 올라갑니다.
코드가 한줄한줄 쭉 나열된 것이 아니라 각각의 기능별로 block을 나누면 코드가 이해하기 쉬워집니다.
나중에 코드를 수정할 일이 있을 때, 코드를 오랜만에 보더라도 잘 나뉘어 있어서 유지보수가 쉬워집니다.
프로그램이 끝날때까지 변수가 살아있는 것이 아니라서(block이 끝나면 local 변수의 삶이 끝나서) 메모리 절약도 됩니다.

또한 마지막으로 한 가지 기억할 것은 한 코드 안에서
서로 다른 block scope를 갖고 있다 하더라도 같은 변수명을 쓰는 것은 지양하도록 하자. 이 역시도 에러를 만들 수 있다.

function logSkyColor() {
const dusk = true;
let myColor = 'blue'; 

if (dusk) {
  let myColor = 'pink';
  console.log(myColor); // pink
}

console.log(myColor); // blue 
}

console.log(myColor); // 에러!!

항상 새로운 변수명을 써야 한다는 점을 꼭 기억하도록 하자!

이 말은 local 변수는 {} - block이 끝나면 더 이상 변수가 살아있지 않고 쓸 수 없다는 말입니다.

profile
?

0개의 댓글