-
23_10_07 JS공부정리개발공부/JavaScript 2023. 10. 8. 01:54
https://www.youtube.com/watch?v=9nZ3gOS5wlA&list=PLcqDmjxt30RvEEN6eUCcSrrH-hKjCT4wt&index=84
[제로초강의] 10.2강~
<배운것>
-input에 value를 문자열이 아니라 숫자로 넣고싶으면 type="number"를 넣고, 이걸 JS에서 이벤트 발생값을 가져올때는 event.target.valueAsNumber를 쓰면 된다. (.value로 잡으면 문자열이됨)
<input id="menu-input" type="number"/>$gameMenu.addEventListener('submit', (event) => {event.preventDefault();const input = event.target['menu-input'].valueAsNumber; //이렇게 하면 input으로 받는 값의 type은 number가 됨-깊은복사와 얕은복사
-깊은복사 : 아예 새로운 객체를 만들어냄. 겉과 속(객체안의 객체속 요소들)까지 모두 복사하여 복사본이 바뀌어도 원본의 겉과 속이 안바뀜.
const monsterList = [{ name: '슬라임', hp: 25, att: 10, xp: 10 },{ name: '스켈레톤', hp: 50, att: 15, xp: 20 },{ name: '마왕', hp: 150, att: 35, xp: 50 },];
const monster1 = JSON.parse(JSON.stringify(monsterList[0])); //깊은복사const monster2 = monsterList[0]; //참조monster1.name = "새 몬스터";console.log(mosterList[0].name); // 슬라임. 깊은복사를 하니 만들어진 객체를 변경해도 원본이 변경되지 않음moster2.name = "새 몬스터";console.log(monsterList[0]name); // 새 몬스터. 참조하고있는 원본의 값도 변경됨.console.log(monsterList[0] === monster1); // false, 깊은복사. 원본과 다른 새로운 객체가 만들어짐console.log(mosterList[0] === monster2); // true, 참조관계, 원본을 참조하는 객체이므로 같음-JSON.parse(JSON.stringify(객체))는 성능도 느리고 함수나 Math,Date 같은 객체를 복사 못하기 때문에 실무에서는 lodash의 clone과 같은 라이브러리를 사용함.
-얕은복사 : 겉만 복사하고 속은 복사못하는 것. 객체 안의 객체가 있을경우 안쪽 객체의 변화는 참조로 인해 같이 변화함.
얕은복사된 arr2의 요소를 바꾸어도 원본이 변경되지 않음 하지만 객체안의 객체의 요소들은 원본과 동일하게 바뀜. const array = [{j : 'k'}, {l : 'm'}];const shallowCopy = [...array]; //얕은복사console.log(array === shallowCopy); // false. 객체의 겉은 복사됨console.log(array[0] === shallowCopy[0]); //true 객체속의 요소는 참조관계임.-[...배열], {...객체}, 배열.slice()/ 배열.concat() 은 얕은복사 방법이다.
-this가 객체안에 있을때는 객체를 가리키고, 아닐때는 window를 가리킨다.
const hero = {name: '',lev: 1,maxHp: 100,hp: 100,xp: 0,att: 10,attack(moster) {monster.hp -= this.att;this.hp -= monster.att;}heal(monster) {this.hp += 20;this.hp -= monster.att; //여기에서 this는 hero객체를 가리킨다.}};attack: (moster) => {monster.hp -= this.att;this.hp -= monster.att; //화살표함수를 쓰게되면 this는 브라우저총괄객체인 window를 가리키게됨.} //따라서 this를 쓸땐 화살표함수를 써서는 안됨.-new연산자와 생성자함수.
-함수앞에 new를 붙이면 함수실행전 가상의 객체를 만들어내고 가상의 객체에 this에 할당함.
https://ko.javascript.info/constructor-new
new 연산자와 생성자 함수
ko.javascript.info
function Monster(name, hp, att, xp) { //생성자함수this.name = name;this.hp = hp;this.att = att;this.xp = xp;}Monster.prototype.attack = function(monster) {//메서드같은경우 생성자함수에 넣기 힘들어서 밖으로 빼야함.(Class를 이용해야하는 이유)monster.hp -= this.att;this.hp -= monster.att;}
const monster1 = new Monster('슬라임', 25, 10, 11); //new를 생성자앞에 붙여줌.const monster2 = new Monster('슬라임', 26, 10, 10); //new를 빼면 this는 window를 가리키게됨.-Class는 객체를 생성하기 위한 템플릿이다.
-new를 빼면 this는 window를 가리키지 않고 에러가 남.
https://ko.javascript.info/class
클래스와 기본 문법
ko.javascript.info
class Monster{ //생성자constructor(name, hp, att, xp) {this.name = name;this.hp = hp;this.att = att;this.xp = xp;}attack(monster) { //Class를 이용하면 생성자함수와는 다르게 생성자안에 메서드를 넣을 수 있음.monster.hp -= this.att; //화살표함수를 사용하면 this는 window를 가리키게됨.this.hp -= monster.att;}}const monster1 = new Monster('슬라임', 25, 10, 11); // Class,생성자 new를 이용하여 새 객체 생성const monster2 = new Monster('슬라임', 26, 10, 10);-태그.addEventListener에서 this를 사용하면 태그를 가리킴.
(정확히는 addEventListener가 콜백함수의 this를 event.target으로 바꾸는것)
-그래서 addEventListener를 쓸때 삽입할 함수에 this가 들어가면 함수를 화살표함수로 만들어줘야함.
-화살표함수를 하면 안쪽의 this는 바깥쪽의 this를 그대로 받아옴. 그래서 addEventListener 밖과 안의 this가 동일해지는것
$gameMenu.addEventListener('submit', function (event) {event.preventDefault();const input = event.target['menu-input'].value;if (input === '1') { // 모험console.log(this); //이 this는 $gameMenu를 가리킴.this.changeScreen('battle');} else if (input === '2') { // 휴식} else if (input === '3') { // 종료}});console.log(this)의 결과. $gameMenu인 form태그를 가리킴 $gameMenu.addEventListener('submit', (event) => { //이렇게 화살표함수를 만들면 $gameMenu가 아니라 상위의 객체를 가리키게됨event.preventDefault();const input = event.target['menu-input'].value;if (input === '1') { // 모험console.log(this);this.changeScreen('battle');} else if (input === '2') { // 휴식} else if (input === '3') { // 종료}});console.log(this)를 한 결과. 생성자인 Game을 가리킴 -함수.bind(객체)();를 통해 함수안의 this가 가리킬 객체를 지정할 수 있음
function a() {console.log(this);}a.bind(document)(); //this는 window가 아니라 document를 가리킴. bind로 this가 가리킬 객체를 선택가능.-단, 화살표함수는 bind를 쓸수 없음.(함수밖의 this를 받아오기때문임)
const a = () => {console.log(this);}b.bind(document)(); //window가 출력됨. 화살표함수는 bind를 못한다.-클래스 상속
class Unit { //부모클래스constructor(game, name, hp, att, xp) {this.game = game;this.name = name;this.maxHp = hp;this.hp = hp;this.xp = xp;this.att = att;}attack(target) {target.hp -= this.att;}}
class Hero extends Unit { //상속할 객체를 extends Unit으로 표현. 부모에 있는 모든 값들이 여기서도 적용됨(메서드포함)constructor(game, name){super(game, name, 100, 10, 0); //상속할 것들을 super()로 표현가능.this.lev = 1;}attack(target) {super.attack(target); //부모클래스의 메서드를 이렇게 가져올수 잇음. 메서드가 아예 같으면 모두생략도 가능.console.log("영웅공격");}heal(monster){this.hp += 20;this.hp -= monster.att;}getXp(xp) {this.xp += xp;if (this.xp >= this.lev * 15) {this.xp -= this.lev * 15;this.lev += 1;this.maxHp += 5;this.att += 5;this.hp = this.maxHp;this.game.showMessage(`레벨업! 레벨 ${this.lev}`);}}}'개발공부 > JavaScript' 카테고리의 다른 글
23_10_10 JS공부정리 (0) 2023.10.11 23_10_08 JS공부정리 (0) 2023.10.09 23_10_06 JS공부정리 (1) 2023.10.07 23_10_05 JS공부정리 (1) 2023.10.06 23_10_01 JS공부정리 (1) 2023.10.02