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;
이거는 변수선언은 된것인데, 내가 값을 넣지않아도 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;
}
pause 가 true이면 있으면 나갈 수있다.
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 |