배움 __IL/TIL 1기

TIL : 27번째- 230104 [1-1-수]

Mo_bi!e 2023. 1. 4. 19:31

 

 

I. INTRO : 지난시간

II. 값 변수 컬렉션 : ES6

1. Binary and octal Literals

ES6는 몇가지 달라졌다.

 

(1). 2진수와 8진수의 기호를 표현할 수있다. : 기존에 없던 값 표현식으로 이진수(b)와 8진수(o)가 추가되었다

ES6에서 이제 표현하는 방법이 추가되었다 

 

2. let 키워드

기존 문제점

(1) 기존 변수의 문제점1 : 변수를 선언하지 않아도 변수?를 사용할수 있다.

기존에는 붙이지 않아도 사용이 가능했다

 

window로했다 

var는 함수 안이 아니면 뭘 해도 window의 속성으로 붙는다.

암묵적 전역변수 양산할  수있다.

 

(2) 문제점2: 변수를 중복해서 선언해도 문제가없다.

의도하지않은 변수값의 변경가능성이 크다.

 

기존에는 해도 에러가 안났다.

이미 선언한적있다고 나온다 (already been declared)

 

 

3. let 키워드 2 :이젠 지역변수가 생겼다.

(1) 문제점4 : 함수를 하지않으면 지역화 불가능 (함수레벨스코프)

-해결  : 괄호 블록사용하면 지역변수로 사용된다.

undefined 가 된다.

 

(2) 변수의 가시 영역이 생겼다 : var Declarations and Hoisting

기존은 var는 괄호 상관없이 어디나 다 가능했음

 

 

- let으로 선언후 실행하면 오류가 발생 : 변수의 정상화

 

const let 사용하고, 가급적 var 안쓰는게 바람직하다.

 

4. let 키워드3

(1) 가시영역 이해 테스트

1)

console.log(x);
var x = 3;

console.log(y);
let y = 3;

각 실행결과는?

x는 호이스팅 결과 undefined로 초기화 되어서 undefined가 나온다

y느 호이스팅 때 초기화 하지않는다. 그래서 미리 이용할수 없다.(아래 2)와 동일)

 

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

2)

console.log(x);
let x = 3;

let 일시

이거는 변수선언은 된것인데, 내가 값을 넣지않아도 undefiend (var기준)처럼들어가는 것이다.

현재 초기화되지 않은 쓰래기 값 상태이다.

 

이전에 자바에서는 비초기화 지역변수는 쓸수없다. 에러가 떳다 초기화가 안되어서

 

여기도 마찬가지이지만, 변수선언은 이미 되었다.

왜냐하면 코드실행과 상관없이 이미 준비되어있는것이기 때문이다.

 

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

3)

for문도 마찬가지

for의 index값도 var의 경우 원래 영향을 미치지만 let을 쓰면 함수 스코프가 정해져서 문제가 해결이 된다.

 

 

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

4)

전역변수와 지역변수 

 

기존 var의 경우 곧바로 선언하게 되면 window객체의 프로퍼티가 된다.

그러나 let의 경우 그렇다고 하더라도 window객체의 프로퍼티가 아니라, 보이지않는 개념적 블록에 존재한다.

 

 

5. const 키워드

(1) 상수형변수를 선언할 수있다 : 방향코드 생성 : 방향을 위한 값을 숫자로 정의하기

1)방향코드 생성 : 방향을 위한 값 숫자로 정의하기

숫자는 자체가 의미가 없다 숫자는 인간에게 어울리는것이 아님

우리는 심벌을 넣어야한다.

 

2) 문자로 정의하기

각 값은 고정되어야한다. 이 값이 바뀌는것을 막기위해서 const를 쓴다.

 

- 값을 비교하거나 넘길때 문자열 써도된다. 

 

코드를 문자어로 표현하고싶을 때 이고, 그래서 대문자로 표현하는것이 좋다.

 

6. 템플릿 스트링 (Template literal)

let year = 2023;
let month = 01;
let day = 03;

//1번방법
let regdate = year+"-"+month+"-"+day;
console.log(regdate);

//2번방법
let template = `${year}-${month}-${day}`; //이것은 `로 감싸야만 사용가능하다
console.log(template);

위 아래 콘솔에 결과는 동일하다


<문자열 인터폴레이션(String Interpolation)>

1번방법으로도 쉽게 할 수있지만 +의 연속으로 번거로움이있다.

2번방법으로 `$ {} 으로 탬플릿으로 이용이 가능하다

 

`을 하면 탬플릿이 가능한데, 위가 더 편하다고 할수도있다.

연산자($ {})가 더 많이 들어가서 복잡할수도있다.

예시로 상품목록에서 데이터가 포함되어야함

let product = "<section class = "p-elect">";

"" 이 연달아 나와서 겹쳐버림

아니면 방지위해서 (\)이스케이프 쓰거나 / 싱글('')로 쓰면된다

 

그러나 싱글로 해결안되는 경우도 있음

긴 태그들을 줄 내려쓰면 범위가 끊어져 버린다.

이런 에러 방지위해서 +(더하기)를 쓴다.

ES5 는 \로 +를 갈음하기가 가능하다.

 

그러나 이거보다도 밖을 ``(백틱) 으로 범위를 다 잡아버릴 수있다.

let product = `<section class = "p-elect">
                    <h1>?</h1>
                </section>`;

 

문자열이 복잡할수록 탬플릿으로 하면 좋다

내려쓰기가 가능하다는것은 큰 의미가 없음, 그거보다는 값들을 어디에 꽂아넣을 때 좋다.

 

let product2 = `<section class =`+ className +`>
                    <h1>`+`</h1>
                </section>`;

이런 방식은 어디까지가 덧셈인지 혼란스럽다.

let product3 = `<section class = "${className}">
                    <h1>${title}</h1>
                </section>`;

이런식으로 하면 유용하게 이용가능하다 이미 산업계에서 많이들 이용한다. JS에 도입되었다.

이렇게 문자열 가지고있는 녀석을 사용 할 때 좋다

 

문자열사이에 \n을 쓰면 내려쓰기가 된다. 만약 \n자체를 표현하고 싶으면 \ 를 한번 더 써주면 된다.

 

let product3 = String.raw `<section class = "${className}"> \n\n\n
                    <h1>${title}</h1>
                </section>`;

이거 외에도 string.raw를 하면 \n이 그대로 표현된다.

 

 

7. 향상된 JSON 객체 표현식

이전과 다르게 향상된 것이다. 

 

(1) 개별 값 데이터를 JSON 객체에 담기

키 변수 명 너무 비슷하면 중복되는 느낌이 있다.

 

(2) 객체 초기화의 변화 : 속성 초기화에서 키 이름과 값 변수의 이름이 같다면 생략할 수있다.

{kor : kor} => {kor} .....

 

(3) function 키워드를 생략할 수있다.

total:function() {} ==> total(){}

 

가급적 이것저것 쓰기보다는 하나로 정해서 쓰는것이 바람직하다.

 

(4) 객체 초기화의 변화 2 : computed property : 속성명을 정의할 때 변수를 사용할수 있게 되었다.S

약속장소에 친구없을 시 대기 하는데 값이 바뀌더라도 변수명은 바꿀수없다.

값은 당연히 바뀌는데 변수명도 바뀐다는 것은 좋지않다.

친구따라 같이 장소바뀌는거 처럼...

 

변수명은 쉽게 바꾸면안된다. 이 경우 []로 이용해서 가능하다.

 

let attrName = "kor";

let exam = {
    // attrName : 100, //[]없으면 undefined 가 나온다. 
    [attrName] : 100, //[]있으니 변수명이 바뀌어도 값이 나온다. 
    eng : 20,
    math : 30
};

console.log(`kor: ${exam.kor}`);

  이런경우 변수명이 바뀔 수 있다.

let attrName = "korean";

로 바뀌면 또 undefined 가 나온다.

이거는 추후 공개

 

프로퍼티 키 동적 생성

8. 객체 Destructuring

지역변수 선언방법이 달라진것일 뿐이다.

이전까지는 개별적으로 선언을 해주었다. 객체의 속성값을 잡기위해서...

5개를 개별적 받고 대입했는데, 이런 작업을 줄여주는 연산이 추가되었다.

 

(1) 데이터 구조는 중첩을 낮춰서 사용할 것

지역적으로 넣어줄때 여러번 반복을 막자

 

(2) 객제의 속성을 사용할때

지역적으로 넣어줄때 여러번 반복을 막자

 

(3) ES6 에서 지원해주는 Destructuring

1)

let {eng ,kor} = exam; // 내가 하고싶은 속성만 가능하다.

console.log(kor, eng);

내가 원하는 방식으로 exma객체를 파괴해서 동일한 키 값에 할당이 가능하다.

 

2)

let {english ,kor} = exam; // 내가 하고싶은 속성만 가능하다.

console.log(english);

콘솔에서 undefined 가 나온다.

 

별칭 방식으로 가능하다.

 

3)

let {eng: english ,kor} = exam; // 별칭 만들기

console.log(english);

사이에 : 표시로 가능하다

 

4) 

let {eng: english ,ma =0} = exam; // 내가 하고싶은 속성만 가능하다.

console.log(ma);

 

5)

그렇다면 객체의 속성이 또다른 객체가 있을 때 이부분만 지역변수로 뽀개기가 가능할까?

let exam = {
    // attrName : 100, //[]없으면 undefined 가 나온다. 
    [attrName] : 100, //[]있으니 변수명이 바뀌어도 값이 나온다. 
    eng : 20,
    math : 30,

    student:{
        name : 'newLec',
        phone : '010-2222-3333'

    }
};

console.log(`kor: ${exam.kor}`);

let {eng: english ,ma =0, student:{name ,phone}} = exam; // 내가 하고싶은 속성만 가능하다.

console.log(ma);
console.log(english);
console.log(name);

객체형태 변수 리스트에 필요한 값을 넣어준다.

 

destructring 할 때 또 다른 객체는 아래와같이 이용해야한다.

 

let {eng: english ,ma =0, student} = exam; // 내가 하고싶은 속성만 가능하다.
let {name, phone} = student;

console.log(student.name);
console.log(phone);

두번뽀개기 하거나 아니면 한번 뽀개고 student.name으로 접근이 가능하다. 

 

III. 값 변수 컬렉션 : ES6

1. run() : window.setTimeout

window.addEventListener("load",function(){

    const gamecanvas = new Gamecanvas();
    gamecanvas.run();
    //스스로 다른것을 가져오는게 바로 안된다.
    //html에 요구해야한다

});

무한히 심장뛰게끔 해야한다. 여기안에는 무한루프로 들어가야한다.

ui 스레드를 잡아먹으면서보다 건드리지않으면서 하는것이 바람직하다

(1) window.setTimeout

1) setTimeout

알람맞추기 1회성 알람을 setTimeout라고한다

매일 알람은 setInterval이다

//3초뒤 보너스타임시작 용으로 가능
    window.setTimeout(function(){
        console.log("time out");
    },1000);

이렇게 하면 1초뒤에 콘솔에 나오게끔 할 수있다.

 

☆ : 우리 게임에 보너스타임 시작시 적용이 가능한 부분이다

 

2) 계속 실행

window.setTimeout(this.run.bind(this),1000);

어제와 마찬가지로 우리가 의도하는 객체에 바인딩되어야하는것은 window가 아니라 game-canvas이다.

그러나 이를 호출 함수의 객체는 window이기 때문에 bind를 이용해주어야한다.

 

3) Arrow 함수(화살표함수) : ES6 도입

이 함수는 상위 함수의 this를 언제나 가르킨다. 이를 Lexical this(즉 정적this)라고 한다.

 

<규칙>

익명함수로만 가능하다

생성자 함수, 객체의 메소드를 제외한 모든함수(내부함수, 콜백함수)에 이용한다. [bind 등도 가능]

 

 

// 호출 주체
    window.setTimeout(function(){
        this.run(); //이 경우 this는 window이다. 
        //여기 함수 실행주체가 window이기 때문이다.
    })

//화살표함수
    window.setTimeout(()=>{

        //이경우 자기 this가 아니라 바로 밖에 있는 this를 쓴다.
        //무조건이기 보다, 얘는 지역화(자기만의 영역,this)가 없기 때문에 이거를 쓴다
        //즉 간단하게 한단하게 할때 이용이 용이하다.
		this.run();
        
    },500))

()이 부분은 인수를 받는부분 

=> 이 부분은 화살표함수를 가르키는 부분

{} 이 부분은 그 영역을 의미한다.

 

위의 경우 this가 있는곳은 내부함수이다. 그 결과 window를 가르킨다.

 

이를 해결하기위해서 동일한 방식으로 화살표함수를 쓸수있다.

Lexcial this로서 바로 상위함수의 this를 정적으로 지정한다.

 

 

(2) 멈추기

이 경우 멈추는 것은 어떡해야할까? 내외부 두가지 방식이 있다.

내부는 알아서 끝내게끔 하거나 gameOver변수로... 

 

실제로 멈추는 것은 게임오버가 애니메이션

window.addEventListener("load",function(){

    const gamecanvas = new Gamecanvas();
    gamecanvas.run();
    //스스로 다른것을 가져오는게 바로 안된다.
    //html에 요구해야한다

    gamecanvas.pause();

});
class Gamecanvas{ //생성자 만들기

    constructor(){

    //  this.dom = document.querySelector(".game-canvas");
    // //이미 캔버스라서 dom으로 하자
    // /**@type {CanvasRenderingContext2D};*/
    // this.ctx = this.dom.getContext("2d");
    // this.boy = new Boy(100,100);

	//게임 상태변수
    this.gameover = false;
    this.pause = false;

    // this.dom.onclick = this.clickHandler.bind(this);
    //  //bind는 호출할때가 아니라 위임할 때
    }
run(){
	//pause 가 false 였다가 true면 나간다
        if(this.pause)
            return;
            }

pausetrue이면 있으면 나갈 수있다.

 

gameOver는 내 캐릭터가 살아있을 수 없음 의미한다.

적들은 움직인다. 내 아바타만 죽는거야 

이게 pause 와의 차이이다.

clickHandler(){
        this.pause = true;
    }

클릭하면 멈추게 된다.

 

 

(3) 움직이게 하기

캔버스는 사용자의 입력 전달하는역할이다.

 

UI건너편에는 내 아바타가 있다.

그런데 스스로가 아니라, 얘를 품고있는 그쪽세상에서의 지령자가 있어야한다.

지령을 내를 수있도록하는 것이 UI이다.

 

문제는 움직임이 한번이 아니라 점진적이다.

사용자 입력

 

(4) 터치위치로 순간이동(?) 한다.

1)

업데이트를 잘 이해하지못하면 순간이동한다.

이렇게 안되고 부드럽게 하려면 나누어서 가게끔해야한다.

단위 벡터 쪼개서 하는 업데이트 작업을 해주어야한다.

 

이 경우 위치 x,y를 바로 바꾸면 안되고

목적지를 넣지, 상태값을 바꾸면 안된다. 쪼개어서 가야한다.

 

하나 이동 단위 기준벡터라 한다.

<이미지>

 

 

2) 적기와 달리 아군기는 터치한 곳으로 일정시간 안에 와야함

근거리 VS 원거리  

 

시간 내에 도착하기 위해 멀리있으면 빨리와야한다.

 

단위 벡터의 크기에 차이가 없음

길이가 멀던 가깝던 단위간격이 동일하다.  

 

 

거리 (d) = x^2 + y^2 (루트) [피타고라스정리의 응용]

대각선 거리가 1씩값을 주기위해서는 x가 얼만큼 y가 얼만큼 이동할지 알아내야햔다

왜? 대각선 길이가 1이 되기 위해서

 

★ 다섯개의 단위 벡터를 합쳐서 x,y값을 구하기 가능

d 의 길이를 구하고,

 

3) 실습

- 순간이동

class Boy{
moveTo(x,y){

    this.x = x;
    this.y = y;
    // 이렇게 하면안됨 왜냐하면 바로 순간이동하게된다.

}

순간이동 된다. 점진적이지않다.

 

 

- 해보았으나, x,y 가 정의되지 않았다고 나온다.

불났을 때 어디서 났는지 처럼

이벤트(클릭)가 일어났을 때 어디서 났는지 궁금하다 

 

class Gamecanvas{
clickHandler(e){

        // this.pause = true;
        this.boy.moveTo(e.x,e.y);
        //e.x e.y 이벤트 발생한 x,y 좌표가 나온다.

    }

e라는 인수로서 x,y값을 받아줄수 있다.

업데이트로 이제 자연스럽게 할 수있다.

 

우리는 구조를 이해해야한다

update, draw 관계를 이해하는것이 바람직하다.

 

-이 경우 

class Boy{
    constructor(x , y){
 
 // 1)
        //벡터
        this.vx = 0;
        this.vy = 0;

        //목적지
        this.dx = 0;
        this.dy = 0;
        
        //시작 기본위치 정해주기
        this.x = x || 100;
        this.y = y || 100;
         
    }
//5)
	update(){
        //여기서 점진적으로 그리기 위한 용도
        this.x += this.vx;
        this.y += this.vy;

    }


    moveTo(dx,dy){

//2)
        //목적지에서 현재위치를 빼서
        //가로세로 를 지정한다
        let w = dx - this.x;
        let h = dy - this.y;
//3)
        //구해진 가로세로로 거리로
        // 총 거리를 구한다
        let d = Math.sqrt(w * w + h * h);
//4)
        //x,y 좌표 벡터값을 구한다.
        this. vx = w / d;
        this. vy = h / d;

    }
    }

내가 이해한것을 바탕으로 보면

1) 생성자에 벡터변수와 목적지 변수를 초기화해준다

 

2) moveTo 에 들어온 인수를 기준으로 목적지 좌표(dx,dy)를 받아서 현재 목적지 좌표(x,y)를 빼주어서 그 차이의 높이와 너비를 구한다.

 

3) 구해진 높이와 너비로 피타고라스 정리로 총 거리를 구한다

 

4) 총거리 대비해서 움직여야하는 높이와 너비로 벡터값(vx,vy)를 구한다.

즉 나누기를 이용해서 벡터의 단위를 구해준다.

 

5) 이후 업데이트된 벡터값을 다시 x,y에 넣어주어서 이동시켜준다.

이 경우 구해진 벡터값으로 지속해서 x,y에다가 더해주어서 넣어준다.

 

다만 5)은 멈추는것이 없어서 지속해서 클릭한 방향으로 무한반복으로 더해준다.

그래서 멈추지않는다.

다음시간에는 이것을 해결할 것이다.

 

 


1. 보충

(1) 호이스팅

 

What (정의) : 인터프리터가 함수와 변수를 선언전에 메모리에 공간에 할당하는 것이다.

var의 경우에는 undefined로 초기화하고 나온다

let const는 초기화하지않는다.

 

(2) 이동 벡터

 

(3) 

 

 

2. 회고 

0) 오늘이 오류

update() 메소드를 아래쪽에 하나 더 선언되어있어서, 의도한 메소드가 호출되지않고 엉뚱한 동일명의 메소드가 호출되었다. 이 점은 var 처럼 에러라고 표시도 안되어서 골치거리이다. 이 점에서 JS의 한계점을 오늘 경험하게되었다. 

 

1)  es6 에 들어오고 나서 더 손쉬운방법을 보니 반갑다

 

2) 화살표 함수를 공부하면서 this에 대한 제대로된 이해를 한층 더 할수있어서 기분이좋다

 

3) window.setTimeout 으로 일정한 조건을 넣어주면 무한반복을 while(true)처럼 쓸수있는것이 흥미로웠다

 

 

 

'배움 __IL > TIL 1기' 카테고리의 다른 글

TIL : 29번째- 230106 [1-1-금]  (0) 2023.01.06
TIL : 28번째- 230105 [1-1-목]  (0) 2023.01.05
TIL : 26번째- 230103 [1-1-화]  (0) 2023.01.03
TIL : 25번째- 230102 [1-1-월]  (0) 2023.01.02
TIL : 24번째- 221230 [12-5-금]  (0) 2022.12.30