JavaScript/DreamCoding

JS operator, if, for loop 알아보기

느리지만 꾸준하게 2021. 8. 2. 18:38

연산으로 넘어가기 전에 Variable(let)과 Constant(const)의 차이점 / Mutable 데이터 타입과 Immutable 데이터타입을 살펴보았다. 

Variable은 메모리에 값을 읽고 쓰는게 가능하다. 사용자가 jay라고 값을 할당한 다음에 hello로변경이 가능한 것이 variable의 읽고 쓰기가 가능하기(r/w) 때문이다. 반대로 const는 읽기만 가능하다.(r) 그래서 const를 선언하고 값을 할당한 뒤로는 자물쇠가 생겨서 읽기만 가능하고 다른값으로 쓰는 것이 불가능하다.

let과 const 비교

JS에서는 변수의 값이 계속 바껴야 될 이유가 없다면 왠만하면 const를 사용하자. 그리고 메모리에 값이 저장되는 방법은 primitive 타입인지 object 타입인지에 따라서 메모리에 다른 방식으로 저장이 된다. primitive 타입의 경우에는 값 자체가 메모리에 저장된다. object의 경우에는 너무커서 메모리에 한 번에 다 못올라간다. 그래서 const jay라고 선언하고 ojbect를 할당하게 되면 jay가 가리키고 있는 곳에는 레퍼런스가 있다. 레퍼런스는 실제로 오브젝트를 가리키고 있는 공간이다. 그래서 레퍼런스를 통해서 실제로 오브젝트가 담겨있는 메모리를 가리키게 된다. 그래서 const jay라고 선언하게 되면 jay가 가리키고 있는 포인터만 담겨서 jay가 다른 오브젝트로 변경이 불가능하다. jay의 이름과 나이는 계속 변경이 가능하다.

 

primitibe 타입의 메모리 저장방식(let)
object타입의 메모리 저장방식(const)

다시 정리하면 데이터타입에는 Immutable 데이터 타입과 Mutable data 타입이 있다. Immutable 데이터타입은 데이터 자체를 절대 변경 못하는 것이고, primitive 데이터 타입같은 경우는 jay라는 string을 정하게 되면 jay를 통째로 메모리에 올렸다가 다른 string로 변경이 가능하지만 jay라는 string 자체를 jay라고 하는 것은 하지 못한다.

 

반대로 변경이 가능한 데이터타입은 object이다. object는 계속 스스로 변경이 가능하기 때문에 mutable 데이터 타입이다. JS에서 기본적으로 모든 objec는 변경이 가능하다. JS에서 array배열은 mutable 데이터 타입인데 간혹가다 다른언어에서는 mutable array와 immutable array 두가지를 분리해서 따로 존재하는 경우도 있다. JS에서는 모든 object는 mutable하다.

 

이제 operator에 대해서 알아보면 먼저 String concatenation

String concatenation은 문자열과 문자열을 더해서 나타낼 수도 문자열과 숫자를 합해서 문자열로 나타낼 수도 있고, 

백틱 ` 기호를 사용해서 string literals를 나타낼 수도 있다. $을 이용하면 string으로 포함해서 문자를 만들게 된다. string의 좋은점은 중간에 ''''(single quote)을 사용해도 그대로 문자열로 나온다. ''(single quote)이용해서 문자열을 만들면 '(single quote)이 인식이 안되는데 백슬래쉬를 이용하면 나타낼 수 있다. 새로 줄바꿈은 백슬러쉬n을 이용하면 된다.

백슬러쉬t는 tab키이고 이러한 특수문자열도 익숙해지자.

string concatenation

다음으로는 Numeric operators인데 사칙연산과 나머지 제곱 등이 있다.

세 번째로는 Increment Decrement operator이다. counter라는 변수가 있으면 변수앞에 ++를 넣으면 preincrement라고 하고 이것은 counter +1 해서 counter에 값을 다시 할당한 것과 같다.

반대로 postincrement는 변수다음에 ++를 붙이게 되면 먼저 변수의 값을 postIncrement에 할당한 다음에 그 뒤에 counter의 값을 1을 증가시키는 counter가 2로 시작해서 위에서 1증가해서 3 다시 1증가해서 4로 업데이트가 된다.

--도 똑같다. 아래 그림을 살펴보자

increment decrement operator

네 번째는 = operators(assignment operators)인데 x = x + y를 아래와 같이 생략해서 코드를 작성할 수 있다.

= operators

다음으로 비교하는 operator이다. 작거나 크거나 작거나같거나 크거나같거나

여섯 번째로 logical operators인데 or and not 이 3가지 연산자가 있는데 value나 expression중에서 세개중에 하나라도 true가 있으면 true로 계산이 되는 연산자이다. 아래 그림을 보면 value1은 true이고 value2는 false 이지만 check는 true이므로 (계속 가다가 true를 리턴함) 전체값이 true로 return이 된다.

 

or 연산자는 처음으로 true가 나오면 뒤에가 true든 false든 거기서 멈춘다. 그래서 wasting time 부분을 출력하지 않고 바로 true로 출력한다. 그리고 연산이 무거운 check를 맨앞에다가 놓으면 안되고 simple한 value 같은 것들을 제일 앞다가 놓아야 한다. and &&연산자도 비슷하다. 대신에 3개다 true가 되어야 true이다. 

logical operator

그리고 and는 null체크할 때도 많이 쓰이는데 object가 null이면 false가 되기 때문에 뒤에가 실행이 안된다. 즉 nullobject가 null이 아닐때만 something을 받아오게 된다. 간편하게 코드를 작성하면 아래와 같다.

 

다음으로 not연산자는 값을 반대로 바꿔준다. 아래와 같이 value1이 true기 때문에 false로 바꿔준다.

일곱번째로 Equality operators가 있다.

두개의 ==sign을 쓰게되면 loose equality라고 하게 된다. 즉 타입을 변경해서 검사를 하기 때문이다. 즉 아래그림과 같이 stringFive나 numberFive나 두개는 같다라고 나온다. 그리고 같지않다라고 하면 false로 나온다. 그래서 js엔진은 문자열이긴 한데 안에있는 건 숫자5니까 두개 다 같다라고 나온다. 세 개의 === sign은 strict equality로써 타입을 신경써서 타입이 다르면 다른 것이다라고 판단한다. ===로 판단하면 false로 나오고 !==로하면 true로 나온다.

그래서 코딩할 때 왠만하면 strict equality를 사용해서 검사하는게 좋다. equality를 공부할 때 objet를 저 유심있게 보면  object는 메모리에 탑재될 때 레퍼런스형태로 저장된다고 했는데 ellie1과 ellie2는 똑같은 데이터가 들어있는 object이지만 실제로 메모리에는 1과 2에는 각각 다른 레퍼런스가 들어있고 그 다른 레퍼런스는 서로 다른 오브젝트를 가리키고 있다. 그리고 ellie3은 ellie1의 레퍼런스가 할당되어 있으니까 똑같은 레퍼런스를 가지고 있게된다. 그러면 아래그림과 같이 콘솔을 찍으면 ellie1과 ellie2는 ==찍었을 때 각각 다른 레퍼런스가 들어있어서 false이고 ellie1 ellie2는 같은 타입이든 아니든 ===를 찍었을 때 레퍼런스 값이 다르기 때문에 false이고 ellie1과 ellie3는 같다 왜냐 elli1이 가지고 있는 레퍼런스 value를 ellie3으로 할당했기 때문이다.

 

아래그림과 같이 equality -puzzer 그림을 보게되면 0과 null undefined는 false로 간주될 수 있으니까 t로 하고(==일때) 하지만 0은 boolean타입이 아니기 때문에 ===을 이용하게 되면 false로 나오게 된다. '' empty 문자열은 false맞고

그리고 ===(strict equality)일때 ''은 boolean타입이 아니기 때문에 false와 비교했을 때 false로 나오게 된다. null은 undefined라고 ==비교했을 때 같은것으로 간주되지만, null과 undefined는 다른타입이기 때문에 === 비교할 때 false로 나오게 된다.

 

다음으로 If operators를 보게되면 if statement는 이 statement가 true이면 그 안에 있는 블럭을 실행하게 된다. 이름이 엘리인가? 그러면 첫번째 콘솔로그를 출력하고 jay가 아니고 코더이면 두번째 콘솔을 출력하고 그거도 아니면 언논을 출력하게 된다.

if operator

다음으로 if를 간단하게 쓸 수 있는 ? operators이다 if statement에다가 ?를 붙인것이다. 즉 true인가? true이면 yes를 출력하고 아니면 no를 출력하라고 한다. 그래서 값을 할당하거나 간단하게 출력할 때 이걸 많이 쓴다.

이 ternary operator을 계속해서 묶고 묶고 반복해서 쓰면 코드의 가독성이 떨어지기 때문에 대신에 if나 switch를 쓰는게 더 맞다. 이것은 간단할 때만 쓰는게 적당하다.

? operator

다음으로 switch operators인데 브라우저에 있는 값이 IE이면 첫번쨰 콘솔로그를 찍고 멈추고 크롬이면 콘솔찍고 멈추고 이런식이다. 아래는 IE이기 때문에 go away가 나오는데 chrome이나 firefox일때는 똑같은 메세지를 출력한다고 하면 연달아서 붙어서 쓰면 자동적으로 묶어서 출력이 된다. 간편하게 쓸 수 있어서 switch도 좋다.

if에서 elseif elseif 반복에서 출력한다면 switch를 쓰는게 좋다.

switch문

다음으로는 while loop문인데 while같은 경우는 statement가 false로 나오기 전까지 무한대로 반복해서 계속해서 도는것을 말한다. i가 0보다 클 때까지는 계속해서 출력하는 것을 아래그림과 같이 볼 수 있다.

반대로 do-while loop는 먼저 블럭을 실행한 다음에 조건이 맞는지 안맞는지를 실행한다. 그래서 위에서 실행하고 난 다음에 i가 0으로 됐는데 0이 됐음에도 불구하고 출력이 먼저되고 나서 i가 0인지 아닌지 검사해서 멈추게 되는 것을 볼 수가 있다. 그래서 블럭을 먼저 실행하고 싶다면 do-while을 써야하고 조건문이 맞을때만 블럭을 실행하고 싶다면 while을 쓰면된다.

 

다음으로 for loop에 대해서 보면 for 같은 경우는 시작하는 문장 컨디션이 중간에 오고 스텝을 밟아나갈껀지를 명시하게 되어있다. 그래서 bigin은 한 번만 실행하게 되는데 i를 3으로 준비시켜놓고 i가 0보다 크다하면 콘솔로그를 출력하게 되고 3 2 1로 출력이 된다. 그래서 기존에 존재하는 변수에 할당하는 경우도 있고 for안에서 블럭안에 let이라는 지역변수를 선언해서 작성할 수도 아ㅣㅆ다.

while이나 for같은거는 서로 nesting해서 작성할 수가 있는데 for문 안에 for 이중for문을 작성하게 되면

i가 0일때 j를 0부터 9까지 돌리고 i가 1일때 j를 0부터 9까지 돌리고 하는 식으로 nesting해서 작성하게 되면 bigO가 n**2이다. 그래서 cpu에 좋지 않고 되도록이면 피하는게 좋다.

마지막으로 break와 continue가 있는데 break는 루프를 완전히 끝내는 거고 continue는 지금꺼만 스킵하고 다음스텝으로 넘어가는 것을 말한다. 

짝수만 출력하는 코드를 작성하면 숫자가 홀수인 경우에는 continue를 사용해서 콘솔이 출력안되도록 넘어가는 식으로 작성하면 된다. 

 

 

 

 

 

 

참고: https://www.youtube.com/watch?v=YBjufjBaxHo&list=PLv2d7VI9OotTVOL4QmPfvJWPJvkmv6h-2&index=4