자바스크립트 #06 로또추첨기

수박·2020년 6월 10일
0

JavaScript

목록 보기
7/22

자바스크립트 #06 로또추첨기

로또번호는 45개이다.

이 번호들을 담는 배열부터 만들어보자.

var numCandidate = Array(45);

해당 번호를 콘솔을 해봤을 때 45개의 모든 요소는 empty로 초기화되어있다.

empty에는 접근할 수 없으므로 undefined로 초기화 시켜준다.

초기화를 시켜주기 위해서 fill()메소드를 사용한다.

numCandidate.fill();

empty의 값을 가지던 배열들이 undefined로 초기화되었다.

이제 해당 배열에 1~45의 값을 가지게 해보자.

반복문(foreach), 매핑(map)을 이용해서 데이터를 넣어보자

var num = Array(45).fill();

num.forEach(function(value, index){
    num[index] = value + 3;
    //num[index] = index + 1;
});

console.log(num);

처음부터 배열의 끝까지 반복하는 foreach를 사용했다.

여기서 value는 현재 배열의 값이고, 인덱스는 배열의 인덱스이다.

(키, 값이 매개변수라고 생각하면 편함)

num배열은 fill로 채웠으니 모든 원소의 값이 undefined인 상태이다. 따라서 value에는 아무런 값도 존재하지 않는다.

인덱스는 0부터시작하니 0부터 44까지 1을 더해서 num배열의 value로 넣어준다.


map으로 데이터 삽입하기

map은 배열의 메소드이다.

마찬가지로 매개변수는 배열.map(요소, 인덱스, 배열)으로 foreach와 동일하다.

map은 return값을 배열의 값으로 넣어준다.

var num = Array(45).fill().map(function(value, index){
	return (index + 1);
});

foreach와 같은 결과를 얻을 수 있다!

result = oneTwoThree.map((v) => {
  if (v % 2) {
    return '홀수';
  }
  return '짝수';
});

이런 방법도 가능하다. foreach도 되는거 아닌가


셔플

데이터를 삽입을 했으면 이제 랜덤하게 뽑아야한다.

후보군배열에서 랜덤한 데이터를 뽑아 셔플배열에 넣는다.

랜덤한 수를 만들어내는 Math.random함수, 그리고 내림하는 Math.floor를 사용해보자

Math.floor(Math.random() * 범위);

random()은 0에서 0.9999..까지 랜덤한 수를 생성한다.

범위에 10을 넣으면 0~9까지 데이터를 뽑는다는 의미이다.

올림을 사용해버리면 0.000001이 나왔을때 1의 값을 내므로 0의 데이터를 뽑을 수 없다.

var shuffle = [];

while(numCandidate.length > 0)
{
    var pickNum = numCandidate.splice(Math.floor(Math.random() * numCandidate.length), 1)[0];
    shuffle.push(pickNum);
}

console.log(shuffle);

splice메소드는 매개변수로 (처음, 끝)만큼을 자르는 값을 받고, 배열을 반환하므로 현재 사용하는 로직에서 1가지의 숫자만을 뽑기때문에 배열의 첫번째값[0]을 반환하도록 작성한다.

이렇게 얻어진 데이터를 slice메소드를 통해 앞에서 5개의 번호를 뽑아보자.

var winNum = shuffle.slice(0,6);
console.log(winNum+" bonus "+bonus);

결과물을 출력했을때 정렬이 되지 않은상태로 출력이 된다.

정렬하는 방법은 다음과 같다.

var winNum = shuffle.slice(0,6).sort(function(p, c){ return p - c;});

p , c는 비교로 들어갈 데이터이고, 해당 값이 양수이면 오름차순, 음수이면 내림차순으로 들어간다.

만약 7 3 2 4 1 이 있으면 7-3 = 4이므로 양수이다. 이렇게 됐을때 정렬방법은 오름차순이 된다.


클로저??

반복문안에 setTimeout이라는 비동기함수를 사용할 때 제대로 수행되지 않는다.

해당 강의에서는 클로저 문제로 인한 것이라한다.

클로저에 대해 학습했다.

자바스크립트는 함수마다 스코프가 생성이 된다.

스코프란 어느 변수에 접근할 수 있는 범위 라고한다.

스코프에는 전역, 지역스코프가 존재한다.

전역변수, 지역변수와 같은 의미라고 이해했다.

만약 함수내에 선언된 변수가 없다면 (지역스코프가 존재하지 않는다면 scope chain을 통해 해당 변수를 찾는다.

함수의 지역스코프 이외에 블록 스코프라는 것도 존재한다.

중괄호로 둘러싸게 되는 것이다. 함수스코프에서만 지역스코프를 지닐 수 있었는데, ES6에서 let, const키워드가 추가되면서 {} 안에 선언된 블록에서도 지역변수를 선언할 수 있게 되었다.

var d = 'D';

function outer(){
	var a = 1;
    var b = 'B';
    function inner(){
        var a = 2;
		console.log(a);
		console.log(b);
		console.log(d);
    }
    inner();
}

outer();

스코프체인이란 스코프끼리 연결된 것을 의미한다.

함수 동작순서는 밖에서 outer를 호출하고, a =1, b='B'로 매핑한다음, inner메소드를 수행한다.

inner에서 a를 콘솔해보면 2가 출력된다.

inner의 스코프의 a는 2값을 갖기 때문이다.

그리고 b값을 찍어보면 outer의 B가 출력된다.

inner의 스코프안에는 b가 존재하지 않기 때문에 스코프를 이동하여 찾는다.

다시 d를 로그할때 inner에 없고, outer에 없고 전역스코프에 d값이 존재하기 때문에 X를 출력하게 된다,.

스코프의 연결 - 이동이 바로 스코프체인의 의미이다.

그렇다면 클로저는 도대체 뭘까???

코드를 보자!

var d = 'D';

function outer(){
	var a = 1;
    var b = 'B';
    function inner(){
        var a = 2;
		console.log(a);
		console.log(b);
		console.log(d);
    }
    return inner;
}

var someFun = outer();
someFun();

먼저 return inner에 대해서 알아보자.

https://offbyone.tistory.com/135

https://okky.kr/article/706753

자바스크립트에서 함수는 변수에 담을 수 있다.

위의 코드에서 outer함수는 inner함수를 반환한다.

이를 받는 someFun변수는 함수를 반환받았기 때문에 함수로 호출이 가능한 것이다.

someFun을 클로저라고한다.

outer함수의 종료이후 사라져야할 스코프들이 호출 후에도 존재한다는 것이다. 클로저는 자신(inner)을 포함하고 있는 외부함수(outer)의 인자, 지역 변수(a,b)등을 외부 함수가 종료된 이후에도 사용할 수 있다.

for(let i = 0; i < winNum.length; i++)
{
    setTimeout(function callback(){
        var numberValue = document.createElement('div');
        numberValue.textContent = winNum[i];
        resultDiv.appendChild(numberValue);
    }, (i + 1) * 1000);
    // var numberValue = document.createElement('div');
    // numberValue.textContent = winNum[i];
    // resultDiv.appendChild(numberValue);
}

아!!!!!!!!!내가 뭘 이해하는지 모르겠다.. setTimeout은 비동기함수니 호출시점이 달라서 function의 지역스코프가 아닌 블록스코프를 갖게하는 let변수를 i로 두지 않고 var으로 반복문을 돌리면 지역스코프가 존재하지 않기 때문에 비동기함수인 setTimeout의 i값이 for문의 최종값으로 호출하는 것인가 ..?!@?#!?@#! 머라고 쓰는지 모르겠다..

아직 js에 대해 많이 몰라서 이해가 안가는 것인지 뭑 맞는 것인지 !

결과

이 과제는 따로 해보고 싶었기 때문에 더 이쁘게 만들어서 dothome에 서비스해볼 예정임!

0개의 댓글