TIL | JS Repl.it 23,24

임채현·2022년 1월 3일
0

Object1

처음에는 당연히 저 인자 3개만 더하면 되겠지하고 세 인자의 합을 구하는 코드를 작성하였으나 이내 인자의 개수는 정해지지 않았다는 것을 깨달았다.

따라서 초기값을 정하고 반복문을 통해 각 인자를 더하는 식의 코드를 작성하였다. (obj보다는 array문제인거 같은거는 기분탓..?)

function getData(salesArr,reviewArr,likeArr){
  let sumAmount = 0;
  let sumReview = 0;
  let sumLike = 0;
  
  for(let i = 0; i < salesArr.length; i++) {
      sumAmount += salesArr[i][1];
    }
  for(let i = 0; i < reviewArr.length; i++) {
      sumReview += reviewArr[i][1];
    }
  for(let i = 0; i < likeArr.length; i++) {
      sumLike += likeArr[i][1];
    }
    
  const objData = {
    sumAmount: sumAmount,
    sumReview: sumReview,
    sumLike: sumLike,
  };
  return objData;
}

Scope

scope은 매우 중요한 개념인 것 같다. 확실히 알아보자!

scope은 javascript에서 문법이 아니라 '변수가 어디까지 쓰일 수 있는지'의 범위를 의미한다.
scope을 알기 위해서는 block을 아는 것이 중요하다.
block이란 {}(중괄호로 감싸진 것)을 말한다.
function이나 for문, if문에서 봐왔던 {}안의 내용이 바로 block이었던 것이다.
HTML의 block이랑 헷갈리지 말자!! 완전히 다른 개념

  • scope은 global(전역)local(지역)로 나뉜다.
    그리고 그 안에서 만들어지는 변수를 전역변수, 지역변수라 한다.

block의 개념을 이용하여 변수의 개념을 재정의할 수 있다.

  • block밖에서 만들어지는 변수를 전역변수라 하고
  • block안의 변수를 지역변수라 한다.

Local Scope vs Global Scope

  1. 모든 변수에는 scope 즉 변수의 유효 범위가 있는데 크게 로컬 변수와 글로벌 변수로 나눌 수 있고, 이를 나누는 기준은 '{}' 블록문이다.
  2. 로컬 변수는 블록 내에서만 유효한 범위를 가지고 있고(Local scope 안쪽에서 선언된 변수는 밖에서 사용할 수 없다) 글로벌 변수는 어디에서나 유효한 범위를 가지고 있다.
  3. 블록문 내에서 변수를 사용하려고 하면 로컬 변수를 먼저 찾아서 사용하고 없을 경우는 글로벌 변수를 사용한다. 글로벌 변수도 없다면 당연히 오류가 발생하게 된다.
  4. 안쪽 scope에서 바깥 변수나 함수에는 접근이 가능하지만 바깥쪽 scope에서 안쪽 변수나 함수에는 접근할 수 없다.
  5. Scope는 중첩할 수 있다.(즉, 함수 안에 함수 넣기가 가능하다)
  6. 지역변수는 함수 내에서 전역 변수보다 더 높은 우선순위를 가진다.

아래의 간단한 예시를 하나 보자

function myFunction() {
 let x = "해리포터";
 x = "호그와트";} 
myFunction();
console.log(x);

위의 예시를 보면 선언한 x는 모두 block내의 지역변수이기 때문에
전역변수 x를 출력하려는 console.log(x)는 아무런 결과를 내놓지 않는다.

Scope을 배우면서 가장 주의깊게 봐야할 것은 scope의 오염이다!

global 변수를 선언하게 되면 해당 변수를 사용할 수 있는 namespace를 가지게 된다. scope이랑 똑같은 말이지만 변수이름을 얘기할 때 많이 다룬다.
local 변수는 {}이 끝나면 사라지는 반면 global 변수는 프로그램이 종료될 때 까지 끝까지 살아있다.
따라서 global 변수를 남발하면 코딩이 길게 진행되는 동안 나도 모르는 변수가 계속 살아있어 변수 선언 및 할당에 지장을 주게되고 이는 scope pollution을 초래한다.
아래는 scope pollution의 대표적인 예시이다.

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

const callMyNightSky = () => {
  stars = 'Sirius';
  
  return 'Night Sky: ' + satellite + ', ' + stars + ', ' + galaxy;
};

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

stars 변수를 let을 이용하여 선언하였기 때문에 이는 후에 재선언에 따라 할당된 값이 변할 수 있는 여지를 준다.
이제 여기서 문제가 발생한다.
stars의 값을 let을 빼고 선언하는 바람에 지역변수로 선언되야할 stars가 전역변수인 stars로 재선언되었고 값은 'Sirius'로 재할당된다.
이로 인해 우리가 사용하기로 의도한 전역변수의 값 'North Star'이 'Sirius'로 수정되었고 scope pollution이 일어난다.

위와 같이 global 변수가 여기저기서 수정되는 참사를 방지하기 위해서는 변수들을 block scope으로 최대한 나눠놔야 한다.

var vs let vs const

  • var는 되도록이면 사용하지 않도록 한다. (Block Scope의 경우 var로 선언하면 전역변수로 바뀌게 된다)
  • let은 한번 할당된 변수값을 재이용해서 다른 값으로 할당할 일이 생겼을 때 사용하기 좋다.
  • const는 코딩을 하다가 내가 이미 할당한 값을 보호하고 싶을 때 사용한다.

var vs let 보충

var 키워드로 선언된 변수의 유효범위는?

var로 선언한 함수는 함수 스코프 변수이다.

  • 함수 내부에서 var로 변수를 선언하였다면 함수 내부에서만 접근할 수 있는 지역변수가 된다.
  • 따라서 위의 함수 스코프 변수는 함수 밖에서 접근 불가능하다.

반면 let은 블록 스코프 변수를 선언하는 키워드이다.

  • 블록의 단위는 중괄호{}이며
  • 블록 안에서 변수를 선언하면 변수가 선언된 블록과 그 하위 블록에서만 접근이 가능하다.

Var 과 Let 비교

가장 큰 차이는 var은 함수 내부에서 선언되면 어디든지 접근가능하지만 let은 함수 내부라도 블록의 구분에 따라 접근 가능한 범위가 정해진다.

let은 변수 재선언이 불가능하여 이미 변수의 이름을 지정하면 동일한 이름의 변수를 선언할 수 없다.
하지만 let은 블록스코프변수이므로 블록의 구분에 따라 동일한 변수명으로 선언하여도 블록에 따라 변수값이 다르게 할당된다..(매우 중요)

위코드 scope 마크다운을 보면서 문제점을 발견했다.

동일한 변수명을 사용하여 scope namespace가 오염되었다고 하였지만 let은 블록 스코프 변수로 블록의 구분만 있으면 동일한 변수명으로 선언이 가능하다. 위 같은 경우도 2중 블록안에 myColor은 pink로 존재하고 1중블록안에 myColor가 blue로 존재한다.

아래 출력이 에러가 나는 이유는 전역변수를 출력해야하는데 출력할 전역변수가 선언되지 않았기 때문에 에러가 나는것이다!!

동일한 변수명을 쓰는것과는 전혀 관계없다!!

실제로 저 제일 아래의 코드를 제외하고 jsrun을 실행해보면 pink와 blue가 잘 출력된다.

profile
열심히 살고 싶은 임채현입니다.

0개의 댓글