javaScript/jsDeepDive

전위연산자 & 후위연산자 (+엘리스 토끼굴에 빠진 var)

부엉이사장 2023. 5. 4. 05:48

사실 이건 중요한건 아닌데 모던 js 읽을때 헷갈렸던 부분이다.

 

# 후위연산자

let num = 1;
console.log(num++, "  #A"); // 1 #A
console.log(num, "  #B"); // 2 #B

일단 num에 1을 할당하고 여기에 후위연산자를 붙여서 콘솔로 찍어보면

A부분에 1로 뜬다. 응? 난 분명 1을 증가시켰는데?

그래서 B에서 다시 num을 참조하려고 하면 증가된 2를 볼 수 있다.

 

# 전위연산자

let num = 1;
console.log(++num, "  #A"); // 2 #A
console.log(num, "  #B"); // 2 #B

이곳에선 결과가 다르게 뜬다.

 

 

# 두 차이는 무엇일까?

- 후위 연산자는 원래 num의 값을 가지고 있어서 참조시에는 원래 num의 값을 출력한다.

그 후에 num을 증가시킨다.

 

- 전위 연산자는 증가시키고 바로 할당을 해버린다. 따라서 증가된 num의 값을 출력한다.

 

 

 

# while 반복문에서 후위증가연산자

let i = 1;
while (i) {
  if (i < 3) {
    console.log(i++);
  } else {
    break;
  }
}

console.log(i, "마지막 i값"); //3

 

while문의 알고리즘으로 생각해보자.

- 처음 i는 1이다.

-  while(i)조건에서 i 는 1이므로 true이다.

- if문 조건에서 i 는 1이고 3보다 작다.

- 콘솔에 i++를 찍는데 후위연산자이므로 증가되기전인 1값을 출력한다. (출력!)

- 출력후 i값을 증가시켜 2가된다.

- while(i)조건에서 i 는 2이므로 true이다.

- if문 조건에서 i는 2이고 3보다 작다.

- 콘솔에 i++를 찍는데 후위연산자이므로 증가되기전인 2값을 출력한다. (출력!)

- 출력후 i값을 증가시켜 3이된다.

- while(i)조건에서 i 는 3이므로 true이다.

- if문 조건에서 i는 3이고 3보다 작지않다

- else문으로 넘어간다. (break!)

- 마지막으로 스코프 밖에서 i를 찍어보면 3이 나온다.(출력!)

 

 

# while 반복문에서 전위증가연산자

let i = 1;
while (i) {
  if (i < 3) {
    console.log(++i);
  } else {
    break;
  }
}

console.log(i, "마지막 i값"); //3

 

- 처음 i는 1이다.

-  while(i)조건에서 i 는 1이므로 true이다.

- if문 조건에서 i 는 1이고 3보다 작다.

- 콘솔에 ++i를 찍는데 전위연산자이므로 이미 증가되었다. 1에서 1 증가된 2값을 출력한다. (출력!)

- while(i)조건에서 i 는 2이므로 true이다.

- if문 조건에서 i는 2이고 3보다 작다.

- 콘솔에 ++i를 찍는데 전위연산자이므로 이미 증가되었다. 2에서 1 증가된 3값을 출력한다. (출력!)

- while(i)조건에서 i 는 3이므로 true이다.

- if문 조건에서 i는 3이고 3보다 작지않다

- else문으로 넘어간다. (break!)

- 마지막으로 스코프 밖에서 i를 찍어보면 3이 나온다. (출력!)

 

 

 

 

# for 반복문에서 후위증가연산자 (함정)

for (let i = 0; i < 3; i++) {
  console.log(i);
}
console.log(i, "마지막 i값");

이번엔 for 반복문에서 알고리즘을 생각해보자.

결과는 어떻게될까?

참조에러 뜹니다..

얕은 함정을 파봤다. 왜 var보다 let으로 선언문을 써야하는지 나온다.

이런 에러가 뜨면 설명할 줄 알아야 한다.

 

설명을 위해 for반복문에서 let을 var로 바꿔보겠다.

 

for (var i = 0; i < 3; i++) {
  console.log(i);
}
console.log(i, "마지막 i값");

정상적으로 작동된다.

왜일까? 

 

- let으로 선언한 i값의 경우 스코프(범위)

위 설명처럼 let으로 선언한 변수는 스코프안에서만 활동할 수 있다.

때문에 for반복문 스코프 안에서 참조를 하려고 한다면 정상작동을 한다.

그러나 반복문 스코프 밖에서 i를 찍으려는 저 코드가 있는 스코프는 전역스코프다.

이 전역스코프에서는 i를 선언하지 않았기때문에 참조할 i가 없다.

때문에 reference error가 뜬것이다.

for (let i = 0; i < 3; i++) {
  console.log(i);
}

그래서 저 밖에서 i참조하려는 코드를 지우면 정상 작동한다.

 

- var로 선언한 i값의 경우 스코프(범위)

var로 선언하는 변수의 경우 블록스코프를 무시한다. 

블록스코프는 일반적인 스코프 for반복문 스코프, 조건문 스코프 다 통틀어서 적용된다.

때문에 블록안에서 var로 선언한 변수는 전역변수가 되어버린다..ㄷㄷ

이게 무서운게 코드를 수만줄 쓰다보면 변수이름을 똑같이 해버리는 실수를 가끔 하게되는데

스코프를 넘나드는 난봉꾼 변수가 있으면 에러가 터져도 찾기 졸라 힘들게된다.

 

++ var로 선언한 변수는 블록이 몇개로 감싸져 있든 다무시함

위 사진은 j가 반복문 스코프안에 조건문 스코프로 두번이나 감쌌지만 전역스코프에서 j를 참조한다 ㄷㄷ

 

 

때문에 var를 안쓰는 이유중 한가지가 이거다.

 

 

++ 참고로 블록스코프를 무시하는것이지 함수스코프는 무시하지않는다.

reference에러뜸

 

 

 

 

말이 길었다. 왜 es6부터 var말고 let쓰라는지 이유중 중요한 하나가 이거다.

암튼 후위연산자의 for반복문 알고리즘을 다시 보자

 

 

 

 

 

# for 반복문에서 후위증가연산자 (찐)

for (let i = 0; i < 3; i++) {
  console.log(i);
}

- 맨처음 i는 0이다. 

- for 반복문 조건에서 i 0은 3보다 작은가? true

- 콘솔로 i를 출력(0)한다  (출력!)

- i의 값을 증가시킨다. 0 > 1, 여기서 i++(0)값자체는 참조되지 않는다.

- i의 값이 1이 되었다.

- for 반복문 조건에서 i 1은 3보다 작은가? true

- 콘솔로 i를 출력(1)한다  (출력!)

- i의 값을 증가시킨다. 1 > 2, 여기서 i++(1)값자체는 참조되지 않는다.

- i의 값이 2가 되었다.

- for 반복문 조건에서 i 2는 3보다 작은가? true

- 콘솔로 i를 출력(2)한다  (출력!)

- i의 값을 증가시킨다. 2 > 3, 여기서 i++(2)값자체는 참조되지 않는다.

- i의 값이 3이 되었다.

- for 반복문 조건에서 i 3은 3보다 작은가? false

- 끝

 

 

 

 

# for 반복문에서 전위증가연산자

for (let i = 0; i < 3; ++i) {
  console.log(i);
}

- 맨처음 i는 0이다.

- for 반복문 조건에서 i 0은 3보다 작은가? true

- 콘솔로 i를 출력(0)한다  (출력!)

- i의 값을 증가시킨다. 0 > 1

- i의 값이 1이 되었다.

- for 반복문 조건에서 i 1은 3보다 작은가? true

- 콘솔로 i를 출력(1)한다  (출력!)

- i의 값을 증가시킨다. 1 > 2

- i의 값이 2가 되었다.

- for 반복문 조건에서 i 2는 3보다 작은가? true

- 콘솔로 i를 출력(2)한다  (출력!)

- i의 값을 증가시킨다. 2 > 3

- i의 값이 3이 되었다.

- for 반복문 조건에서 i 3은 3보다 작은가? false

- 끝

 

 

둘다 똑같은 출력을 뱉는다.

전위 후위연산자는 크게 중요하지 않는것같다..

근데 모던자바스크립트 읽을때 이해안되서 좀 정확히 하고싶어서 다시 봤다.

 

사실 여기서 var과 let의 스코프차이가 엄청 중요하다.