본문 바로가기

카테고리 없음

[ javascript ] 정리1

브라우저마다 자바스크립트를 컴파일(인터프리터일걸?) 할 수 있는 엔진을 내장하고 있다.

기본적으로 자바스크립트는 한 줄씩 번역한다. 자바스크립트는 기본적으로 브라우저에서 실행이 가능하고,

html문서에서 <script> 열린 태그와 닫힌 태그 사이에 자바스크립트를 작성한다.

자바스크립트는 시간, 조건, 상황에 맞게 다른 코드를 실행하는 동적인 프로그래밍이다.

변수는 데이터를 저장하는 공간에 이름을 붙여놓고, 자주 사용할 값을 넣어놓는 공간이다.

그리고 값을 사용할 때마다 긴 메모리 주소가 아닌 내가 붙인 이름을 사용하면 내가 원하는 값을 꺼내올 수 있다.

변수를 선언한다는 것은 메모리에 데이터를 저장하는 공간을 확보하는 것을 의미한다.

 

- 변수 선언: 데이터를 저장하는 공간을 확보

- 초기화: 선언한 변수에 처음 값을 넣는 것

- 변수를 선언함과 동시에 초기화하는 것이 일반적이다.

- 변수를 선언했지만 초기화하지 않으면 undefined가 출력된다

→ 데이터를 저장할 공간은 확보했으나 그 공간에 데이터를 저장하지 않고 사용하면

값이 없음을 의미하는 undefined가 출력된다. undefined는 값이 없다는 변수의 상태를 의미하는 것이다.

변수에 값을 저장하고 싶다면 대입(할당)연산자(=)를 사용하여 값을 할당해야 한다.

대입연산자를 기준으로 좌항이 변수, 우항이 데이터로, 우항의 값을 좌항에 저장하게 된다.

하나의 변수에 하나의 값만 저장 가능하다.

 

식별자는 중복되어서는 안된다. 자바스크립트에서 var로 변수를 선언하면 에러가 나지 않으므로 var의 사용을 지양한다.

식별자를 작성할 때 두 단어를 연결할 경우 두 번째 단어의 첫 글자를 대문자로 작성하는 카멜케이스 방식을 사용한다.

예를 들어 my name이라는 의미의 식별자를 사용하고 싶다면 var myName; 이렇게 작성해준다.

언더바(_)기호를 사용해서 my_name 이렇게 작성할 수도 있지만 관례상 카멜케이스를 사용하는 것이 좋다.

언더바 기호를 사용해 두 단어를 연결하는 식별자를 작성하는 방법은 snake case라고 하며 주로 파이썬에서 사용된다.

camel case, snake case 등으로 식별자를 작성하는 이유는 가독성을 향상시키기 위해서다.

 

자바스크립트는 동적 데이터타입 언어라고 한다.

변수를 선언하고, 데이터를 대입하면 값의 데이터 타입에 따라 해당 데이터를 저장할 수 있는 변수의 타입이 자동적으로 결정된다.

→ 변수를 선언할 때 데이터의 타입이 결정되는 것이 아니라 값을 무엇을 대입하느냐에 따라 변수의 데이터 타입이 결정된다.

 

데이터 타입이란 변수에 저장할 수 있는 데이터의 유형이 무엇인지를 알려주는 것이다.

자바스크립트의 데이터 타입은 크게 기본 타입과 객체 타입으로 나뉘어지고,

기본 타입에는 숫자 타입, 문자열 타입, 논리 타입, undefined 타입, null 타입, 심볼 타입, 6가지가 있다.

객체 타입에는 객체, 함수, 배열, 리스트 등이 속한다.

대입되는 데이터(값)에 따라서 변수의 데이터 타입이 자동으로 결정되기 때문에

자바스크립트에서 변수를 선언할 때 변수의 타입을 굳이 명시하지 않아도 된다.

동적으로 데이터 타입이 결정되는 자바스크립트의 특성으로

변수에 데이터를 재할당할 때 대입되는 데이터에 기반하여 데이터의 타입이 결정되기 때문에

어떨 때는 변수의 타입이 문자열 타입일 수 있고, 어떨 때는 변수의 타입이 숫자 타입일 수 있다.

변수 선언 및 초기화후 동일 변수에 재할당하는 데이터에 따라 데이터 타입이 달라진다.

***타입 확인용 키워드 typeof

 

***16진수에서 사용할 수 있는 수는 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 다.

10진수에서 사용할 수 있는 수는 1,2,3,4,5,6,7,8,9다.

16진수에서 사용할 수 있는 수 10부터 15까지를 10진수로 표현할 수 없기에

10부터 15까지 A(10), B(11), C (12),D(13), E(14), F(15) 알파벳으로 하나로 표기하게 된 것.

 

***30을 0으로 몇 번 뺄 수가 있느냐? 뺄 수 없다. 어떠한 숫자든 0으로 나눌 수 없다.

이렇게 어떠한 숫자든 0으로 나눌 경우 Infinity라는 결과가 출력된다.

Infinity라는 값은 사용할 수 없으며 그냥 무한대라는 것을 알려주는 것이다.

단, 0을 0으로 나누었을 경우 NaN이라는 결과가 나오는데 typeof로 찍어보면 number가 출력된다.

NaN은 Not a Number의 약어이며, '숫자가 아니다'라는 의미다. Not a Number가 나오는 출력되는 경우는

잘못된 연산(숫자를 숫자로 나누지 않고, 숫자를 문자열로 나눈다든지 등의)과 표현할 수 없는 값의 결과를 나타낸다.

 

자바스크립트에서는 문자열을 표현할 때 쌍따옴표(""), 홑따옴표('') 둘 다 사용이 가능하다.

단, 홑따옴표를 사용해 문자열을 표현하는 경우가 많다.

자바의 경우 쌍따옴표로 문자열을 나타내며, 문자열을 나타낼 때 홑따옴표를 사용하면 에러가 난다.

백틱(``) 기호도 문자열을 나타내는데 표현하는데, 일반적인 문자열을 표현할 때는 홑따옴표를

어떤 특수 문법을 사용하기 위해서는 백틱 기호를 사용한다.

 

자바스크립트에서 변수에 html구조, 즉 태그를 저장할 때 \t, \n과 같이 제어문자로 줄 개행과 들여쓰기를 하지 않고,

임의적으로 줄 개행과 들여쓰기를 했을 경우 에러가 난다. 한 줄로 작성하는 것이 원칙이다. 그런데 한 줄로 작성했을 때,

저장하고 싶었던 html구조가 그대로 저장되는 것이 아니라 문자열로 인식되는 문제가 발생한다.

예를 들어 var tag = '<ul><li><a href="">Home</a></li></ul>'; 이렇게 선언 및 초기화할 경우 console.log(tag); 를 한다면

결과는 다음과 같이 나온다.

 

그래서 이런 문제를 해결할 때는 \t, \n 과 같은 제어특수문자를 사용하거나 백틱 기호를 사용하면 원하는 결과를 얻을 수 있다.

 

1. \t, \n과 같이 제어특수문자를 사용할 경우

 

 

2. 백틱 기호를 사용할 경우

 

결과

 

 

백틱(``)으로 감싼 문자열을 템플릿 리터럴이라고 하고(ES6부터 나온 문법),

``백틱으로 감싼 문자열(템플릿 리터럴)은 공백과 들여쓰기, 줄 개행 등 모두 문자열로 인정해주기 때문에

\t, \n과 같은 특수기호문자를 사용할 필요가 없다. 그래서 변수에 태그를 저장할 경우 유용하게 사용된다.

 

템플릿 리터럴의 찐 장점: 템플릿 리터럴을 이용한 포맷팅 출력 방식

 

문자열과 문자열을 이어붙이고 싶을 때(결합하고 싶을 때) 덧셈 연산 사용이 가능하고,

문자열과 다른 데이터 타입간의 덧셈 연산은 전체 결과를 문자열 취급을 한다.

변수에 저장된 값을 문자열과 연결할 때 덧셈 기호를 사용할 수도 있지만

템플릿 리터럴을 사용한다면 변수에 저장된 값과 문자열간 결합이 더 쉬워진다.

변수에 저장된 값을 출력하고 싶을 때 백틱기호 안에서 변수를 {}중괄호로 감싸고 앞에 $기호를 붙여준다.

 

예를 들어

var month = 12;

var day = 25;

var ani = '크리스마스';

console.log(`${month}월 ${day}일은 ${ani}입니다.`);

 

결과

 

--------------------------------------------

 

자바스크립트에서 논리 값을 표현할 때 true와 false, 2가지로 나타낼 수 있으며

논리값 표현은 숫자로도 표현가능하다. 숫자 0은 false로 0이 아닌 나머지 정수는 true로 해석이 가능하다.

 

--------------------------------------------

 

값이 없음을 나타내는 null과 undefined

해당 변수에 저장되어 있는 값이 없을 때 출력되는 null과 undefined의 차이는

null은 개발자가 의도적으로 값을 대입하지 않았음을 나타내고 싶을 때, 해당 변수에 null을 직접 대입함으로써 값이 없음을 명시한다.

null을 대입한 변수의 타입은 객체가 된다. null이 대입된 변수는 참조하고 있는 객체가 없다는 것을 의미한다.

undefined는 아직 값이 할당되지 않은 변수에 암묵적으로 할당되는 값이다. 변수를 선언만 하고, 값을 할당(대입)하지 않았을 때 또는

어떤 객체의 없는 속성을 사용할 때 undefined가 출력된다.

 

***undefined 타입

- 값이 아직 할당되지 않은 상태를 나타낼 때 사용된다.

- 변수를 선언했지만 값을 할당하지 않았다면 해당 변수에 undefined가 자동으로 할당된다.

- 변수가 값이 비어있음을 의도적으로 표현하거나 변수에 저장된 값을 알 수 없는 상태라는 것을 나타내려면 null을 대입하고,

undefined는 개발자가 직접 대입하는 일이 거의 없음. 값이 할당되지 않은 변수의 초기값을 위한 예약어임.

 

--------------------------------------------

 

자바스크립트에서 거듭제곱 연산자는 **

 

2의 4승을 구해야할 때

var num = 2; // num이라는 변수에 거듭제곱에 사용되는 숫자를 저장해놓고,

 

console.log(num*num*num*num); // 거듭제곱하려는 수만큼 곱해준다. 또는

 

console.log(Math.pow(num, 4)); // Math클래스의 pow()함수를 이용하거나 또는

// ES7이전에 거듭제곱을 나타내고 싶을 때 사용했던 Math.pow()함수

 

console.log(num**4); // 거듭제곱 연산자를 사용하는 방법도 있다.

// **거듭제곱 연산자는 ES7이후에 나온 거듭제곱 연산자다.

 

 

단항 산술 연산자: ++, --

단항 산술 연산자는 변수를 기준으로 앞에 위치하면 전위 연산자, 뒤에 위치하면 후위 연산자로 나뉘어진다.

 

var a =10;

a++; → 이렇게 단독으로 연산할 경우 단항 산술 연산자를 변수 앞에 붙이거나(전위 연산자), 변수 뒤에 붙이거나(후위 연산자) 결과는 같다.

 

그런데 단항 산술 연산자가 다른 연산자와 함께 사용될 때 전위 연산자와 후위 연산자의 결과가 달라진다.

var a = 10;

var result;

 

// 다른 연산자와 후위 연산자가 함께 사용될 경우 선연산, 후증감: 다른 연산자부터 먼저 연산한 후, 해당 변수의 값을 증가시킨다.

result = a++; 

console.log(`result: ${result}, a: ${a}`);  // result: 10, a: 11

 

-----------------------------version2.

 

// 다른 연산자와 전위 연산자가 함께 사용될 경우 선증감, 후연산: 해당 변수의 값을 먼저 증가시키고, 다른 연산자를 연산한다.

result = ++a; 

console.log(`result: ${result}, a: ${a}`);  // result: 11, a: 11

 

--------------------------------------------

 

복합 대입 연산자: 연산과 대입(할당)을 합쳐놓은 연산자

복합 대입 연산자는 누적해서 값을 연산할 때 유용하게 사용된다.

var i = 9;

// 기존 i가 갖고 있는 값에 3을 더한 값을 변수에 대입한다.

// i = i+3;

i+=3; 

 

비교연산자의 결과는 항상 논리값(true, false)이다.

동등연산자(==)와 일치연산자(===)의 차이, 동등 연산자의 경우 데이터 타입이 서로 다를 때,

타입 변환이 가능하면, 타입을 변환한 뒤 서로 비교해서 결과를 나타낸다.

예를 들어

 

 

// 변수 a의 타입은 number고, 변수 b의 타입은 문자열이다.

var a = 6, b = '6';

 

// 동등연산자를 사용했을 경우 변수 b의 타입은 문자열이지만, 숫자를 가진 문자열이므로, 

// 문자열 타입에서 숫자 타입으로 변환이 가능하기 때문에 데이터 타입을 변환한 후에 같은지를 비교한다.

// 변수 a의 값인 6과 문자열 타입을 숫자 타입으로 변환한 후의 변수 b의 값인 6을 비교했을 때 → 6==6

// 동일함으로 결과는 true가 된다.

console.log(a==b);

 

 

// 일치연산자는 값뿐만 아니라 데이터의 타입까지 일치하는 지를 비교한다 → 엄격하게 검사

// a의 데이터타입은 숫자, b의 데이터 타입은 문자이기 때문에 결과는 false가 된다.

console.log(a===b);

 

// 일치비교(===)에서는 NaN을 주의, NaN은 자신과 일치하지 않는 유일한 값이다.

console.log(NaN===NaN); // 결과는 false

 

// 문자열 비교시 스펠링이 동일하더라도 대소문자를 구분하기 때문에

// 하나의 스펠링이라도 대소문자의 차이가 있다면 false를 반환한다.

console.log('apple'==='Apple'); // 결과는 false

 

--------------------------------------------

 

제어문

 

기본적으로 코드의 흐름은 위에서 아래로 동작한다.

이 흐름을 제어할 수 있다. 제어한다는 것은 위에서 아래로 동작하다가 조건에 따라 아래에서 다시 위로 가서 명령문을 실행하는 것을 의미한다. 흐름을 제어하는 방식에는 제어문이 있다. 제어문은 크게 조건문, 반복문, break문, continue문이 있다.

 

***브라우저에서 입력을 지원하는 함수에는 prompt()가 있다.

prompt() 함수의 매개변수로 문자열을 전달하는데, 문자열은 어떤 입력을 받을 건지 사용자에게 보여줄 메시지다.

prompt() 함수를 통해 입력받은 값은 문자열 타입으로 인식된다. 정수를 받을 때는 prompt()앞에 +플러스기호를 붙여주면

입력받은 값이 숫자타입으로 인식되어 연산시 결과에 문제가 없게 된다. 또는 prompt() 함수로 입력받은 값이 대입된 변수의

데이터 타입을 Number로 형변환해도 무방하다 → Number(변수);

alert() 함수는 브라우저에 알림창을 띄운다.

 

조건문인 if문은 else if(조건식)문으로 if(조건식)문의 조건식 결과가 false일 때 분기를 나눌 수 있다.

조건식의 결과가 true일 때 중첩 if문으로 분기를 나눌 수 있다. 원하는 만큼 분기를 나눌 수 있다.

단, else if문의 조건문을 작성할 때 조건이 겹치지 않아야 한다.

 

논리 연산자(logical operator)

좌항과 우항은 논리값이어야 한다. &&: 양쪽 항의 논리값이 모두 true일 경우에만 전체 결과를 true로 도출한다.

예를 들어 로그인할 경우 아이디가 존재해야 하고(true) 존재하는 아이디의 비밀번호가 일치해야 한다(true)

아이디와 비밀번호가 모두 true여야 전체 결과가 true로 도출되면서 로그인을 가능하게 한다.

- &&(AND): 좌항, 우항이 모두 true여야 전체 결과가 true로 도출된다.

- ||(OR): 좌항, 우항중 하나만 true여도 전체 결과가 true로 도출된다.

 

삼항 조건식 연산자(?)

조건식 ? '좌항':'우항';

조건식의 결과가 true라면 좌항의 값이, false라면 우항의 값이 도출된다.

 

var score = 50;

var result = if(score>=70)? '합격':'불합격'; // result에 대입되는 값은 '불합격'이다.

 

반복문은 특정 블록에 담겨있는 명령문을 반복하고 싶을 때 사용한다.

for문과 while문이 있다. while문은 조건식이 들어간다. 조건식의 결과가 true라면 블록 내부의 실행문이 수행된다.

true라면 계속 블록 내부의 실행문을 수행하다가 조건식이 false일 경우에 반복문이 종료된다.

 

while문

 

// 반복문의 횟수를 제어할 제어변수, 제어변수의 값에 변화를 주고, 변화된 값을 조건식에서 판단했을 때

// true를 반환한다면 while문 블록 내부의 수행문을 실행한다. false를 반환한다면 반복문은 종료된다.

// while문 블록 내부에 제어변수에 변화를 줄 연산을 진행해야 한다.

var n = 1;

 

while(n<=10) /* n이 10보다 작거나 같다면 다음 블록 내부의 수행문을 수행한다,

반복문의 끝을 지정하는 논리형 조건식 */ { 

 

  // while문 블록 내부에는 반복하고자 하는 문장을 작성하다.

  // n이 1이고, 1은 10보다 작으니 아래 수행문을 수행한다.

  // n에는 1이 담겨 있어 1번 손님 안녕하세요. 라는 문장이 콘솔에 찍힌다.

 console.log(`${n}번 손님 안녕하세요.`); 

 n++; // 증감식: 반복문의 종료를 위해 제어변수의 값을 조정(step);

  // n은 증가식에 의해 +1이 연산되어 n에는 2가 대입된다.

}

 

-----------------------------------------------------------------------------------

 

문제로 실습하기

사용자로부터 두 개의 정수를 입력받아(x, y) x부터 y까지 누적 합계를 구한다.

(단, x가 y의 정수보다 크다면 x의 값을 y로, y의 값을 x로 치환한다)

 

var x = +prompt('첫 번째 정수를 입력하세요!');

var y = +prompt('두 번째 정수를 입력하세요!');

 

var total = 0; // 누적합계를 담을 변수

 

/*

- 두 변수에 담긴 값을 치환하는(서로 바꾸는) 방법

 

1. 임시변수를 사용한 치환: 고전적인 방법

- 임시변수를 선언 후 → var temp;

- 두 변수 중( var x = 1, y = 2; ) 하나의 값 혹은 참조를 임시변수에 대입해두고 → temp = x;

- 다른 하나의 변수를 x에 대입한 후 → x = y;

- 임시변수의 값을 y에 대입한다 → y = temp;

 

2. 구조 분해 할당(destructing assignment): 현대적인 문법

 

***자바스크립트에서 객체, 배열을 사용할 때,

키를 가진 데이터 여러 개를 하나의 엔티티에 저장할 때는 객체를,

여러 개의 데이터를 순서대로 저장할 때는 배열을 이용한다.

객체나 배열의 전체 데이터가 아닌 일부의 데이터가 필요할 때 구조 분해 할당을 하여 원하는 값만 얻을 수 있다.

 

var x = 1, y =2; 

[ y, x] = [x, y] → x와 y를 배열로 묶고, 배열의 0번째 인덱스의 값을 변수 y에, 배열의 인덱스 1번째 값을 변수 x에 대입하겠다는 것

위 구조 분해 할당의 기능을 풀어서 작성한다면 다음과 같이 작성할 수 있다 → y = [x, y][0]; x = [x, y][1];

대입 연산자를 기준으로 좌항은 값을 대입할 변수가 위치하며, 우항은 좌항에 대입할 값을 작성한다는 개념을 인지하고 계속 보다보니 이해가 조금된 것 같다.

*/

 

/*

if(x>y) { [y, x] = [x,y] } → 구조 분해 할당을 사용하여 두 변수의 값을 치환하기

y = [x, y][0];

x = [x, y][1];

*/

 

if(x>y) /* x가 y보다 크다면 */ {

    // x의 값을 temp에 대입한 뒤, y의 값을 x에 대입하고, temp의 값을 y에 대입한다.

    var temp = x;

    x = y;

    y = temp;

}

 

var startNumber = x;

 

// x가 y보다 작거나 같다면

while(x<=y) {

    // total += x;

    total = total + x;

    x++;

}

 

console.log(`${startNumber}부터 ${y}까지의 누적합계는 ${total} 입니다.`);

 

-----------------------------------------------------------------------------------

 

for문

for(int i = 0; i<=10; i++){ /* 조건식을 판단해서 true라면 실행될 명령문을 작성한다. */ }

- 세미콜론(;)이 구분자가 되어 첫 번째로 오는 식은 초기식이다.

- int i = 0 은 변수 i에 0을 대입하는데, for문(반복문)에 처음 진입할 때 단 한 번 실행된다.

i<=10 은 조건문으로 변수 i에 저장된 값이 10보다 작거나 같다면 for문의 블록문 내부로 들어가 블록문 내부의 명령문을 실행한다.

- 블록문 내부의 명령문을 모두 실행한 뒤에 i++ 증감식이 실행된다. 그리고 다시 조건식으로 들어가 판단한다. true가 나오면 블록문을 실행한다. 그리고 다시 증감식을 실행, 조건식이 false로 판단될 때까지 반복한다. false로 판단되면 반복문은 종료된다.

 

for(초기식; 조건식; 증감식) { /* 조건식이 true라면 실행될 명령문들 */  }

초기식(for문이라는 반복문에 진입할 때 딱 한번 수행됨) → 조건식: true라면 → 블록문 수행{} → 증감식 수행 → 조건식: true라면 → 블록문 수행{} → 증감식 수행 ......조건식이 false일 때까지 이 싸이클이 반복된다.

 

while문은 반복횟수가 명확하지 않을 때, for문은 반복 횟수가 명확한 경우에 많이 사용된다.

 

-----------------------------------------------------------------------------------

 

for문을 사용하여 팩토리얼 구하기 (실습)

***factorial은 the product of an integer and all the integers below it → 팩토리얼은 주어진 정수(an integer)와 그 정수보다 아래에 있는 모든 양의 정수의 곱을(product) 의미한다. n! = n x (n-1) x (n-2)... x 1 → n개를 줄 세우는 모든 경우의 수

n이 양의 정수일 때 1부터 n까지의 곱을 n!이라 쓰고, n팩토리얼 이라고 읽는다.

***permutation과 factorial 은 다름.

while (true) {
  var num = +prompt('정수를 입력하세요!');

  if (num <= 0 || isNaN(num)) {
    alert('유효한 숫자를 입력해주세요');
    continue;
  }

  // 팩토리얼 구하기
  var total = 1;
  for (var i = num; i >= 1; i--) {
    total = total * i;
  }

  alert(`${num}! : ${total}`);
  break;
}

 

 

-----------------------------------------------------------------------------------

 

구구단 2단부터 9단까지 모두 출력하기(실습)

// 2단부터 9단까지 모두 출력
// for 중첩문-------------------------------------
for (var dan = 2; dan <= 9; dan++) {
  console.log(`*************${dan}단*************`);

  for (var num = 1; num <= 9; num++) {
    console.log(`${dan}x${num}=${dan * num}`);
  }
}

// while 중첩문-------------------------------------
var dan = 2;

// n이 10이라면 false를 반환하면서 반복문이 종료됨.
while (dan < 10) {
  console.log(`*************${dan}단*************`);

  var row = 1;
  while (row < 10) {
    console.log(`${dan}x${row}=${dan * row}`);
    row++;
  }
  dan++;
}

 

-----------------------------------------------------------------------------------

 

정수 한 개를 입력받아서 1부터 입력받은 수까지 모든 소수를 출력하고, 그 소수들의 개수를 구하는 로직을 작성하기

while (true) {
  var input = +prompt('정수를 입력하세요!');

  // 1. 입력한 값이 0보다 작거나 같을 경우
  // 2. 숫자가 아닐경우
  // 3. 정수가 아닌 실수일 경우
  if (input <= 0 || isNaN(input) || !Number.isInteger(input)) {
    alert('유효한 숫자를 입력해주세요!');
    continue;
  }

  // 1부터 입력한 숫자까지(입력 숫자 포함)
  var primeNumbers = [];
  for (var i = 1; i <= input; i++) {
    // 소수인지를 판별하는 로직
    //
    var counting = 0;

    for (var j = 1; j <= i; j++) {
      if (i % j === 0) {
        counting++;
      }
    }

    if (counting === 2) {
      primeNumbers.push(i);
    }
  }

  alert(
    `1~${input} 사이의 소수는 ${[...primeNumbers]}, 총 갯수는 ${
      primeNumbers.length
    } 입니다.`
  );
  break;
}

 

-----------------------------------------------------------------------------------

 

난수(a random number) 생성하기 (실습)

 

Math.random()은 0.0부터(0.0포함) 1.0미만까지의 실수를 발생시킨다.

Math.random() → 0.0 <= ~ < 1.0

Math.random() * 10  → 0.0 <= ~ < 10.0

Math.random() * 10 + 1 → 1.0 <= ~ < 11.0

Math.floor(Math.random() * 10 + 1) → 1 <= ~ < 11 → 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 까지의 범위중 난수가 생성됨

시작숫자를 더해주고, 시작숫자가 1이 아니라면 끝범위의 숫자에서 시작숫자를 빼주고 1을 더해준다.

 

-----------------------------------------------------------------------------------

 

숫자 랜덤 게임 실습

 

var random = Math.floor(Math.random() * 100 + 1);
// console.log(`random: ${random}`);

while (true) {
  var menuNumber = showMenu();

  if (menuNumber === -1) continue;

  var count = initialCount(menuNumber);

  for (var i = 1; i <= count; i++) {
    var inputNumber = inputNumberIsValid();

    if (inputNumber === -1) continue;

    if (inputNumber === random) {
      alert(`성공하셨습니다. ${random} 이었습니다.`);
    }

    if (inputNumber > random) {
      alert(`${inputNumber}보다 아래의 숫자를 입력하세요!`);
    } else {
      if (i === count) {
        alert(
          `입력할 수 있는 기회 ${count}번을 모두 소진하셨습니다.\n정답은 ${random} 이었습니다.\n게임을 종료합니다.`
        );
        break;
      }
      alert(`${inputNumber}보다 위의 숫자를 입력하세요!`);
    }
  }
  break;
}

function showMenu() {
  var num = +prompt(
    '******** 랜덤 숫자 맞추기 게임 ********\n # 난이도를 선택해주세요 \n 1번: 상 (3번의 기회) \n 2번: 중 (6번의 기회)\n 3번: 하 (9번의 기회)'
  );

  if (num <= 0 || num > 3 || isNaN(num) || !Number.isInteger(num)) {
    alert('유효한 숫자를 다시 입력해주세요!');
    num = -1;
  }
  return num;
}

function initialCount(oneToThree) {
  var counting;
  switch (oneToThree) {
    case 1:
      counting = 3;
      break;

    case 2:
      counting = 6;
      break;

    case 1:
      counting = 9;
      break;
  }
  return counting;
}

function inputNumberIsValid() {
  var inputNumber = +prompt('정수를 입력해주세요!');

  if (
    inputNumber <= 0 ||
    isNaN(inputNumber) ||
    !Number.isInteger(inputNumber)
  ) {
    alert(
      `입력하신 ${inputNumber}는 유효하지 않습니다. \n유효한 숫자를 입력해주세요!`
    );
    return (inputNumber = -1);
  }
  return inputNumber;
}

 

---------------------------------------------------------------------

 

암묵적 형변환

 

자바스크립트에서 문자열과 숫자를 더할 경우 숫자를 문자열로 변환한 다음 두 변수의 값을 결합한다.

예를 들어 var ex = 10 + '20';

console.log('ex: '+ex); // 1020이 출력된다. 숫자 10이 문자열로 변환되고, 문자열 '10'과 문자열 '20'이 합쳐진 결과다.

덧셈 연산자는 문자열과의 결합 기능을 제공하지만 *연산자는 문자열과 어떤 기능을 제공하지 않는다.

그래서 문자열과 숫자를 곱할 경우 문자열이 만약 숫자로 구성되어 있다면 해당 문자열을 숫자 타입으로 바꾼다음

곱셈 연산을 수행하기 때문에 var ex2 = 10*'3'; console.log(ex2); 의 출력결과는 30이 나오게 된다.

 

문자열 타입의 암묵적 숫자 변환

var ex3 = +'550';

console.log(typeof ex3); // 타입은 숫자가 나온다.

좌항을 비우고 문자열에 +기호를 붙이면 숫자타입(number)으로 변환된다.

문자열 false의 경우 +기호를 붙이면 숫자타입으로 변환되기는 하나 값은 NaN이 출력된다.

문자를 숫자로 변환하면 NaN이지만 숫자를 문자열 형식으로 작성했다면 +기호를 붙였을 때 숫자가 반환된다.

논리 타입을 암묵적으로 숫자로 변환해준다 → ex3 = +true; console.log(ex3); // 1이 출력된다.

단, 문자타입 true는 값이 NaN이라는 결과가 나온다. ex3 = +'true'; console.log(ex3); // NaN이 출력된다.

ex3 = +null; console.log(ex3); // null을 숫자로 변환하면 0이 출력된다.

ex3 = +NaN; console.log(ex3); // NaN을 숫자로 변환하면 NaN이 출력된다.

 

Truthy와 Falsy

 

if(조건문) → if문의 조건문에는 true와 false, 논리 값만 올 수 있고, 만약 논리 값이 아니라면

자바스크립트에서 암묵적으로 논리타입으로 형변환한 다음 true면 블록문을 수행하고, false라면

블록문을 수행하지 않는다.

 

논리 값이 아닌 값들을 암묵적으로 논리 타입으로 형변환했을 때 true로 변환되는지 false로 변환되는지

확인해보기. if('') console.log('OK1'); → 빈 문자열을 논리타입으로 변환했을 때 false로 평가된다.

if('hello') console.log('ok2'); → 문자열 형식 안에 문자가 있다면 true로 평가된다. 빈 문자열이 아닌

문자열 타입 안에 빈 공백이 있다면 이 또한 true로 평가된다. undefined를 논리타입으로 변환했을 때

false로 평가된다. if(null) console.log('ok4'); → null을 논리타입으로 변경했을 때 false로 평가된다.NaN을 논리타입으로 변환했을 때 false로 평가된다. 숫자 0을 논리타입으로 변환했을 때 false로 평가된다.

빈 배열[], 빈 객체{}는 신기하게도 true로 평가된다.

 

undefinde, null, NaN, 숫자 0, ''(빈 문자열)은 모두 false로 평가된다.

Truthy와 Falsy가 유용하게 사용되는 곳 → 함수가 반환하는 값, 비동기 통신의 결과값들이

정확하게 어떤 값인지 모르더라도 해당 값이 띠고 있는 논리적 평가에 따라 조건문을 더 수월하게 구성할 수 있다.

 

자바는 Truthy, Falsy를 지원하지 않는다.