2023.05.13에 시작한 자바스크립트 공부
달려보자고 ~
01. Hello JavaScript!
** 이용 사이트
=> 이용해서 하려다가 그냥 vscode로 가서 공부 중.... ㅎ
역시 오류 수집가 답게 또 오류 발생
즐겁다 즐거워^^^
https://stackoverflow.com/questions/31778413/run-javascript-in-visual-studio-code
해결중...
해결하다가 그냥 CodeSandbox 로 돌아감...ㅎ
02. 변수와 상수
* 변수 "let"
: 바뀔수 있는 값 >> 한번 값을 선언하고 나서 바꿀 수 있습니다.
: 한번 선언했으면 똑같은 이름으로 선언하지 못한다.
// 가능한 경우
let value = 1;
value = 2;
// 불가능한 경우
let value = 1;
let value = 2; // 오류 발생
** 단, 다른 블록 범위 내에서는 똑같은 이름으로 사용이 가능
* 상수 "const"
: 고정적인 값 >> 한번 선언하고 값이 바뀌지 않는 값
// 불가능한 경우
const a = 1;
a = 2; // 오류 발생
03. 연산자
비교 연산자
두 값이 일치하는지 확인
1) === : 두 값이 일치하는지 확인 ✅ 타입 포함
일치한다면 true, 일치하지 않는다면 false
2) == : 두 값이 일치하는지 확인 ✅ 타입 미포함
일치한다면 true, 일치하지 않는다면 false
-> 숫자 1과 문자 '1' 이 동일한 값으로 간주
-> 0 과 false 도 같은 값으로 간주
-> undefined 와 null 도 같은 값으로 간주
두 값이 일치하지 않는지 확인
1) !== : 두 값이 일치하지 않는지 확인 ✅ 타입 포함
다르면 true, 같으면 false
2) != : 두 값이 일치하지 않는지 확인 ✅ 타입 미포함
다르면 true, 같으면 false
-> 숫자 1과 문자 '1' 이 동일한 값으로 간주
-> 0 과 false 도 같은 값으로 간주
-> undefined 와 null 도 같은 값으로 간주
04. 조건문
if 문
let, const : 다른 블록 범위에서는 똑같은 이름으로 선언 할 수도 있다
const a = 1;
if (true) {
const a = 2;
console.log('if문 안의 a 값은 ' + a); // a = 2
}
console.log('if문 밖의 a 값은 ' + a); // a = 1
if-else 문
만약에 특정 조건이 만족할 때와 만족하지 않을 때 서로 다른 코드를 실행해야 된다면 if-else 구문을 사용
if-else if 문
여러 조건에 따라 다른 작업을 해야 할 때 사용
switch/case 문
특정 값이 무엇이냐에 따라 다른 작업을 수행
const device = 'iphone';
switch (device) {
case 'iphone':
console.log('아이폰!');
break;
case 'ipad':
console.log('아이패드!');
break;
case 'galaxy note':
console.log('갤럭시 노트!');
break;
default:
console.log('모르겠네요..');
}
05. 함수
특정 코드를 하나의 명령으로 실행 할 수 있게 해주는 기능
function add(a, b) {
return a + b;
}
const sum = add(1, 2);
console.log(sum);
함수에서 어떤 값을 받아올지 정해주는데 이를 파라미터(매개변수)라고 부릅니다.
ES6 의 템플릿 리터럴 (Template Literal) 문법
작은따옴표('')가 아닌 백틱(``) 사용
function hello(name) {
console.log(`Hello, ${name}!`); // 'Hello, ' + name + '!'
}
hello('velopert');
화살표 함수
const add = (a, b) => {
return a + b;
};
console.log(add(1, 2));
** 화살표 함수와 일반 function 으로 만든 함수와의 주요 차이점
: 화살표 함수에서 가르키는 this 와 function 에서 가르키는 this 가 서로 다르다.
06. 객체
하나의 이름에 여러 종류의 값을 넣을 수 있다.
const dog = {
name: '멍멍이',
age: 2
};
console.log(dog.name); // 멍멍이
console.log(dog.age); // 2
함수에서 객체를 파라미터로 받기
const ironMan = {
name: '토니 스타크',
actor: '로버트 다우니 주니어',
alias: '아이언맨'
};
const captainAmerica = {
name: '스티븐 로저스',
actor: '크리스 에반스',
alias: '캡틴 아메리카'
};
function print(hero) {
const text = `${hero.alias}(${hero.name}) 역할을 맡은 배우는 ${
hero.actor
} 입니다.`;
console.log(text);
}
print(ironMan); // 아이언맨(토니 스타크) 역할을 맡은 배우는 로버트 다우니 주니어 입니다.
print(captainAmerica); // 캡틴 아메리카(스티븐 로저스) 역할을 맡은 배우는 크리스 에반스 입니다.
👾 객체 비구조화 할당
이 문법은 "객체 구조 분해" 라고 불리기도 합니다.
function print(hero) {
const { alias, name, actor } = hero;
const text = `${alias}(${name}) 역할을 맡은 배우는 ${actor} 입니다.`;
console.log(text);
}
파라미터 단계에서 객체 비구조화 할당
function print({ alias, name, actor }) {
const text = `${alias}(${name}) 역할을 맡은 배우는 ${actor} 입니다.`;
console.log(text);
}
객체 안에 함수 넣기
const dog = {
name: '멍멍이',
sound: '멍멍!',
say: function say() { // say() 없어도 똑같이 작동
console.log(this.sound);
}
};
dog.say(); // 멍멍!
객체 안에 함수를 넣을 때, 화살표 함수로 선언한다면 제대로 작동하지 않습니다.
function 으로 선언한 함수는 this 가 제대로 자신이 속한 객체를 가르키게 되는데, 화살표 함수는 그렇지 않기 때문.
Getter 함수와 Setter 함수
Getter 함수
특정 값을 조회 할 때 우리가 설정한 함수로 연산된 값을 반환
numbers.sum() 을 한 것이 아니라 number.sum 을 조회했을 뿐인데, 함수가 실행되고 그 결과값이 출력
const numbers = {
a: 1,
b: 2,
get sum() {
console.log('sum 함수가 실행됩니다!');
return this.a + this.b;
}
};
console.log(numbers.sum);
numbers.b = 5;
console.log(numbers.sum);
Setter 함수
numbers.a = 5 이렇게 값을 설정했을 때 5 를 함수의 파라미터로 받아오게 됩니다.
아까 전에는 만든 객체에서는 numbers.sum 이 조회 될 때마다 덧셈이 이루어졌었지만, 이제는 a 혹은 b 값이 바뀔 때마다 sum 값을 연산
const numbers = {
_a: 1,
_b: 2,
sum: 3,
calculate() {
console.log('calculate');
this.sum = this._a + this._b;
},
get a() {
return this._a;
},
get b() {
return this._b;
},
set a(value) {
console.log('a가 바뀝니다.');
this._a = value;
this.calculate();
},
set b(value) {
console.log('b가 바뀝니다.');
this._b = value;
this.calculate();
}
};
console.log(numbers.sum); // 3
numbers.a = 5; // a가 바뀝니다. calculate
numbers.b = 7; // b가 바뀝니다. calculate
numbers.a = 9; // a가 바뀝니다. calculate
console.log(numbers.sum); // 16
console.log(numbers.sum); // 16
console.log(numbers.sum); // 16
07. 배열
const objects = [{ name: '멍멍이' }, { name: '야옹이' }];
console.log(objects);
console.log(objects[0]);
console.log(objects[1]);
배열에 새 항목 추가하기 : push
const objects = [{ name: '멍멍이' }, { name: '야옹이' }];
objects.push({
name: '멍뭉이'
});
console.log(objects);
배열의 크기 알아내기 : length
const objects = [{ name: '멍멍이' }, { name: '야옹이' }];
console.log(objects.length); // 2
objects.push({
name: '멍뭉이'
});
console.log(objects.length); // 3
08. 반복문
for
// 기본 구조
for (초기 구문; 조건 구문; 변화 구문;) {
코드
}
// 예시
for (let i = 0; i < 10; i++) {
console.log(i);
}
// 배열에서
const names = ['멍멍이', '야옹이', '멍뭉이'];
for (let i = 0; i < names.length; i++) {
console.log(names[i]);
}
while
let i = 0;
while (i < 10) {
console.log(i);
i++;
}
for...of
배열에 관한 반복문을 돌리기 위해서 만들어진 반복문
let numbers = [10, 20, 30, 40, 50];
for (let number of numbers) {
console.log(number);
}
객체를 위한 반복문 for...in
객체의 정보를 배열 형태로 받아올 수 있는 함수 몇가지
- Object.entries: [[키, 값], [키, 값]] 형태의 배열로 변환
- Object.keys: [키, 키, 키] 형태의 배열로 변환
- Object.values: [값, 값, 값] 형태의 배열로 변환
const doggy = {
name: '멍멍이',
sound: '멍멍',
age: 2
};
console.log(Object.entries(doggy));
console.log(Object.keys(doggy)); // ["name", "sound", "image"]
console.log(Object.values(doggy)); // ["멍멍이", "멍멍", 2]
for...in 사용의 경우
const doggy = {
name: '멍멍이',
sound: '멍멍',
age: 2
};
for (let key in doggy) {
console.log(`${key}: ${doggy[key]}`);
}
break 와 continue
for (let i = 0; i < 10; i++) {
if (i === 2) continue; // 다음 루프를 실행
console.log(i);
if (i === 5) break; // 반복문을 끝내기
}
퀴즈
숫자로 이루어진 배열이 주어졌을 때, 해당 숫자 배열안에 들어있는 숫자 중 3보다 큰 숫자로만 이루어진 배열을 새로 만들어서 반환해보세요.
function biggerThanThree(numbers) {
/* 구현해보세요 */
}
const numbers = [1, 2, 3, 4, 5, 6, 7];
console.log(biggerThanThree(numbers)); // [4, 5, 6, 7]
/* quiz
숫자로 이루어진 배열이 주어졌을 때, 해당 숫자 배열안에 들어있는 숫자 중 3보다 큰 숫자로만 이루어진 배열을 새로 만들어서 반환
*/
function biggerThanThree(numbers) {
/* 구현해보세요 */
const result = [];
for (var i = 0; i < numbers.length; i++) {
if (numbers[i] > 3) {
result.push(numbers[i]);
}
}
return result;
}
const numbers = [1, 2, 3, 4, 5, 6, 7];
console.log(biggerThanThree(numbers)); // [4, 5, 6, 7]
다른 분의 코드
function biggerThanThree(numbers) {
return numbers.filter((number) => number > 3);
}
09. 배열 내장함수
forEach
forEach 함수의 파라미터 : 함수 형태인 "각 원소에 대하여 처리하고 싶은 코드"
콜백함수 : 함수형태의 파라미터를 전달하는 것 (함수를 등록해주면, forEach 가 실행)
배열 안에 있는 모든 원소들을 모두 출력하는 경우
// for문 사용
const superheroes = ['아이언맨', '캡틴 아메리카', '토르', '닥터 스트레인지'];
for (let i = 0; i < superheroes.length; i++) {
console.log(superheroes[i]);
}
// forEach 사용
const superheroes = ['아이언맨', '캡틴 아메리카', '토르', '닥터 스트레인지'];
superheroes.forEach(hero => {
console.log(hero);
});
이 함수의 파라미터 hero는 각 원소를 가르키게 됩니다.
map
배열 안의 각 원소를 변환 할 때 사용 되며, 이 과정에서 새로운 배열이 만들어집니다.
map 함수의 파라미터 : 변화를 주는 함수를 전달 (변화함수)
배열 안의 모든 숫자를 제곱해서 새로운 배열을 만들고 싶다
// for문 사용
const array = [1, 2, 3, 4, 5, 6, 7, 8];
const squared = [];
for (let i = 0; i < array.length; i++) {
squared.push(array[i] * array[i]);
}
console.log(squared);
// forEach 사용
const array = [1, 2, 3, 4, 5, 6, 7, 8];
const squared = [];
array.forEach(n => {
squared.push(n * n);
});
console.log(squared);
// map 사용
const array = [1, 2, 3, 4, 5, 6, 7, 8];
const square = n => n * n;
const squared = array.map(square);
console.log(squared);
변화함수 square 는 파라미터 n 을 받아와서 이를 제곱해줍니다.
array.map 함수를 사용 할 때 square 를 변화함수로 사용함으로서, 내부의 모든 값에 대하여 제곱을 해서 새로운 배열을 생성
변화 함수를 꼭 이름을 붙여서 선언 할 필요 X
const squared = array.map(n => n * n);
console.log(squared);
indexOf
원하는 항목이 몇번째 원소인지 찾아주는 함수
배열 안에 있는 값이 숫자, 문자열, 불리언 경우
const superheroes = ['아이언맨', '캡틴 아메리카', '토르', '닥터 스트레인지'];
const index = superheroes.indexOf('토르');
console.log(index); // 2
findIndex
원하는 항목이 몇번째 원소인지 찾아주는 함수
배열 안에 있는 값이 객체, 배열 경우
const todos = [
{
id: 1,
text: '자바스크립트 입문',
done: true
},
{
id: 2,
text: '함수 배우기',
done: true
},
{
id: 3,
text: '객체와 배열 배우기',
done: true
},
{
id: 4,
text: '배열 내장함수 배우기',
done: false
}
];
const index = todos.findIndex(todo => todo.id === 3);
console.log(index); // 2
find
찾아낸 값이 몇번째인지 알아내는 것이 아니라, 찾아낸 값 자체를 반환하는 함수
const todos = [
{
id: 1,
text: '자바스크립트 입문',
done: true
},
{
id: 2,
text: '함수 배우기',
done: true
},
{
id: 3,
text: '객체와 배열 배우기',
done: true
},
{
id: 4,
text: '배열 내장함수 배우기',
done: false
}
];
const todo = todos.find(todo => todo.id === 3);
console.log(todo);
// 결과
{id: 3, text: "객체와 배열 배우기", done: true}
filter
배열에서 특정 조건을 만족하는 값들만 따로 추출하여 새로운 배열을 만드는 함수
filter 함수에 넣는 파라미터는 조건을 검사하는 함수를 넣어주며, 이 함수의 파라미터로 각 원소의 값을 받아오게 됩니다.
EX ) todos 배열에서 done 값이 false 인 항목들만 따로 추출해서 새로운 배열 만들기
const todos = [
{
id: 1,
text: '자바스크립트 입문',
done: true
},
{
id: 2,
text: '함수 배우기',
done: true
},
{
id: 3,
text: '객체와 배열 배우기',
done: true
},
{
id: 4,
text: '배열 내장함수 배우기',
done: false
}
];
const tasksNotDone = todos.filter(todo => todo.done === false);
console.log(tasksNotDone);
// 결과
[
{
id: 4,
text: '배열 내장 함수 배우기',
done: false
}
];
다른 버전 filter 에 넣어준 함수에서 true 를 반환 ~ 새로운 배열에 따로 추출
만약 todo.done 값이 false 라면, !false 가 되고 이 값은 true 이기 때문에, 이전의 todo.done === false 와 똑같이 작동
splice
배열에서 특정 항목을 제거할 때 사용
첫번째 파라미터는 어떤 인덱스부터 지울지를 의미
두번째 파라미터는 그 인덱스부터 몇개를 지울지를 의미
const numbers = [10, 20, 30, 40];
const index = numbers.indexOf(30);
numbers.splice(index, 1);
console.log(numbers); // [10, 20, 40]
slice
배열을 잘라낼 때 사용 ( 단, 기존의 배열은 건들이지 않는다)
첫번째 파라미터는 어디서부터 자를지를 의미
두번째 파라미터는 어디까지 자를지를 의미
const numbers = [10, 20, 30, 40];
const sliced = numbers.slice(0, 2); // 0부터 시작해서 2전까지
console.log(sliced); // [10, 20]
console.log(numbers); // [10, 20, 30, 40]
shift
첫번째 원소를 배열에서 추출 (추출하는 과정에서 해당 원소는 배열에서 사라짐)
const numbers = [10, 20, 30, 40];
const value = numbers.shift();
console.log(value); // 10
console.log(numbers); // [20, 30, 40]
unshift
배열의 맨 앞에 새 원소를 추가 (shift의 반대)
const numbers = [10, 20, 30, 40];
numbers.unshift(5);
console.log(numbers); // [5, 10, 20, 30, 40]
pop
맨 마지막 항목을 추출
const numbers = [10, 20, 30, 40];
const value = numbers.pop();
console.log(value); // 40
console.log(numbers); // [10, 20, 30]
push
배열의 맨 마지막에 새 항목을 추가 (pop의 반대)
concat
여러개의 배열을 하나의 배열로 합쳐준다.
concat 함수는 arr1 과 arr2 에 변화를 주지 않는다.
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const concated = arr1.concat(arr2);
console.log(concated); // [1, 2, 3, 4, 5, 6]
join
배열 안의 값들을 문자열 형태로 합쳐준다.
const array = [1, 2, 3, 4, 5];
console.log(array.join()); // 1,2,3,4,5
console.log(array.join(' ')); // 1 2 3 4 5
console.log(array.join(', ')); // 1, 2, 3, 4, 5
reduce
reduce 함수에는 두개의 파라미터를 전달
첫번째 파라미터는 accumulator 와 current 를 파라미터로 가져와서 결과를 반환하는 콜백함수
두번째 파라미터는 reduce 함수에서 사용 할 초깃값
주어진 배열에 대하여 총합을 구해야 하는 상황 구현
EX 1 ) 사전에 sum 을 선언하고, forEach 를 통하여 계속해서 덧셈
const numbers = [1, 2, 3, 4, 5];
let sum = array.reduce((accumulator, current) => accumulator + current, 0);
console.log(sum); // 15
EX 2 ) reduce 함수를 사용해 다음과 같이 구현
const numbers = [1, 2, 3, 4, 5];
let sum = array.reduce((accumulator, current) => accumulator + current, 0);
console.log(sum);
const numbers = [1, 2, 3, 4, 5];
let sum = numbers.reduce((accumulator, current) => {
console.log({ accumulator, current });
return accumulator + current;
}, 0);
console.log(sum);
주어진 배열에 대하여 평균을 구해야 하는 상황 구현
추가 파라미터 index 와 array
index : 현재 처리하고 있는 항목이 몇번째인지를 의미
array : 현재 처리하고 있는 배열 자신을 의미
const numbers = [1, 2, 3, 4, 5];
let sum = numbers.reduce((accumulator, current, index, array) => {
if (index === array.length - 1) {
return (accumulator + current) / array.length;
}
return accumulator + current;
}, 0);
console.log(sum); // 3
퀴즈
숫자 배열이 주어졌을 때 10보다 큰 숫자의 갯수를 반환하는 함수를 만드세요.
function countBiggerThanTen(numbers) {
/* 구현해보세요 */
}
const count = countBiggerThanTen([1, 2, 3, 5, 10, 20, 30, 40, 50, 60]);
console.log(count); // 5
답 1
function countBiggerThanTen(numbers) {
/* 구현해보세요 */
num_count = 0;
numbers.forEach(n => {
if (n > 10) {
num_count += 1;
}
});
return num_count;
}
const count = countBiggerThanTen([1, 2, 3, 5, 10, 20, 30, 40, 50, 60]);
console.log(count); // 5
답 2
function countBiggerThanTen(numbers) {
/* 구현해보세요 */
return numbers.reduce((accumulator, current) => {
if (current > 10) {
return accumulator + 1;
} else {
return accumulator;
}
},0);
}
const count = countBiggerThanTen([1, 2, 3, 5, 10, 20, 30, 40, 50, 60]);
console.log(count); // 5
다른 분의 답
function countBiggerThanTen(numbers) {
return numbers.filter(n => n > 10).length;
}
const count = countBiggerThanTen([1, 2, 3, 5, 10, 20, 30, 40, 50, 60]);
console.log(count); // 5
10. 프로토타입과 클래스
객체 생성자
객체 생성자는 함수를 통해서 새로운 객체를 만들고 그 안에 넣고 싶은 값 혹은 함수들을 구현 할 수 있게 해줍니다.
1) 함수 이름 대문자로 시작
2) 새로운 객체를 만들 때에는 new 키워드를 앞에 붙이기
function Animal(type, name, sound) {
this.type = type;
this.name = name;
this.sound = sound;
this.say = function() {
console.log(this.sound);
};
}
const dog = new Animal('개', '멍멍이', '멍멍');
const cat = new Animal('고양이', '야옹이', '야옹');
dog.say(); // 멍멍
cat.say(); // 야옹
프로토타입
같은 객체 생성자 함수를 사용하는 경우, 특정 함수 또는 값을 재사용 가능
객체 생성자 함수 아래에 .prototype.[원하는키] = 코드를 입력하여 설정
function Animal(type, name, sound) {
this.type = type;
this.name = name;
this.sound = sound;
}
Animal.prototype.say = function() {
console.log(this.sound);
};
Animal.prototype.sharedValue = 1;
const dog = new Animal('개', '멍멍이', '멍멍');
const cat = new Animal('고양이', '야옹이', '야옹');
dog.say(); // 멍멍
cat.say(); // 야옹
console.log(dog.sharedValue); // 1
console.log(cat.sharedValue); // 1
객체 생성자 상속받기
첫번째 인자에는 this 를 넣기
그 이후에는 Animal 객체 생성자 함수에서 필요로 하는 파라미터 넣기
prototype 을 공유해야 하기 때문에 상속받은 객체 생성자 함수를 만들고 나서 prototype 값을 Animal.prototype 으로 설정
function Animal(type, name, sound) {
this.type = type;
this.name = name;
this.sound = sound;
}
Animal.prototype.say = function() {
console.log(this.sound);
};
Animal.prototype.sharedValue = 1;
function Dog(name, sound) {
Animal.call(this, '개', name, sound);
}
Dog.prototype = Animal.prototype;
function Cat(name, sound) {
Animal.call(this, '고양이', name, sound);
}
Cat.prototype = Animal.prototype;
const dog = new Dog('멍멍이', '멍멍');
const cat = new Cat('야옹이', '야옹');
dog.say();
cat.say();
클래스
ES5 에서는 클래스 문법이 따로 없었기 때문에 위에서 작성한 코드처럼 객체 생성자 함수를 사용하여 비슷한 작업을 구현
ES6 에서부터는 class 라는 문법이 추가
1) 객체 생성자로 구현했던 코드를 조금 더 명확하고, 깔끔하게 구현 가능
2) 추가적으로, 상속도 훨씬 쉽게 가능
class Animal {
constructor(type, name, sound) {
this.type = type;
this.name = name;
this.sound = sound;
}
say() {
console.log(this.sound);
}
}
const dog = new Animal('개', '멍멍이', '멍멍');
const cat = new Animal('고양이', '야옹이', '야옹');
dog.say(); // 멍멍
cat.say(); // 야옹
- say 라는 함수를 클래스 내부에 선언
- 메서드 : 클래스 내부의 함수
- 메서드를 만들면 자동으로 prototype 으로 등록
class 를 사용 시, 다른 클래스 쉽게 상속 가능
상속을 할 때는 extends 키워드를 사용, constructor에서 사용하는 super() 함수가 상속받은 클래스의 생성자를 가르킴
class Animal {
constructor(type, name, sound) {
this.type = type;
this.name = name;
this.sound = sound;
}
say() {
console.log(this.sound);
}
}
class Dog extends Animal {
constructor(name, sound) {
super('개', name, sound);
}
}
class Cat extends Animal {
constructor(name, sound) {
super('고양이', name, sound);
}
}
const dog = new Dog('멍멍이', '멍멍');
const dog2 = new Dog('왈왈이', '왈왈');
const cat = new Cat('야옹이', '야옹');
const cat2 = new Cat('냐옹이', '냐옹');
dog.say(); // 멍멍
dog2.say(); // 왈왈
cat.say(); // 야옹
cat2.say(); // 냐옹
연습
class Food {
constructor(name) {
this.name = name;
this.brands = [];
}
addBrand(brand) {
this.brands.push(brand)
}
print() {
console.log(`${this.name}을/를 파는 음식점들:`)
console.log(this.brands.join(', '));
}
}
const pizza = new Food('피자');
pizza.addBrand('피자헛');
pizza.addBrand('도미노 피자');
const chicken = new Food('치킨');
chicken.addBrand('굽네치킨');
chicken.addBrand('BBQ');
pizza.print()
chicken.print();
2023.06.11 에 종료... wow...
진짜 오래 끌었다... ㅋㅋㅋㅋㅋㅋㅋㅋ
이제는 문법 공부로 이동!!
** 도움받은 페이지