JavaScript 기초 문법 정리 - 2

bp.chys·2020년 5월 17일
0
post-thumbnail

velopert님의 모던 자바스크립트 강좌를 참고하여 작성했습니다.

배열

배열은 어떤 배열이든 만들수 있다. ex) 숫자배열, 문자열 배열, 객체 배열 등.

객체 배열 선언 및 조회

const objects = [{ name: '아메리카노' }, { name: '스무디' }];

console.log(objects);
console.log(objects[0]);
console.log(objects[1]);

배열에 새 항목 추가하기

push 내장함수를 사용한다.

objects.push({
  name: '카페라떼'
});

배열의 크기는 length 내장함수를 통해서 알아낼 수 있다.

console.log(objects.length);    // 3

반복문

for

for (let i = 0; i < 10; i++) {
  console.log(i)
}

for (초기 구문; 조건 구문; 변화 구문;) {
  코드
}

배열과 for

const names = ['멍멍이', '야옹이', '멍뭉이'];

for (let i = 0; i < names.length; i++) {
  console.log(names[i]);
}

// 멍멍이
// 야옹이
// 멍뭉이

while

특정 조건이 참이라면 계속해서 반복하는 반복문이다.

반복문 내부에서 조건에 변화를 주고 언젠가는 조건이 false가 되도록 만들어주어야 한다. 그렇지 않으면 반복문이 끝나지 않고 영원히 반복되게 된다.

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

  • 객체 정보를 배열형태로 받아올 수 있는 함수들

    • Objects.entries('객체이름') : [[키, 값], [키, 값]] 형태의 배열로 변환
    • Objects.keys('객체이름') : [키, 키, 키] 형태의 배열로 변환
    • Obejcts.values('객체이름') : [값, 값, 값] 형태의 배열로 변환
  • 위 내장함수를 사용하거나 for...in을 사용한다.

    const doggy = {
      name: '멍멍이',
      sound: '멍멍',
      age: 2
    };
    
    for (let key in doggy) {
      console.log(`${key}: ${doggy[key]}`);
    }

break와 continue

반복문안에서는 breakcontinue를 통해서 반복문을 벗어나거나, 그 다음 루프를 돌게끔 할 수 있다.

for (let i = 0; i < 10; i++) {
  if (i === 2) continue; // 다음 루프를 실행
  console.log(i);
  if (i === 5) break; // 반복문을 끝내기
}
// 0, 1, 3, 4, 5 가 차례로 출력된다.

배열 내장 함수

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);
});

이렇게 함수 형태의 파라미터를 전달하는 것을 콜백함수라고 한다. 함수를 등록해주면, forEach가 각각의 요소들을 돌면서 hero라는 인자로 받아서 실행해준다.

map

배열 안의 각 원소를 변환할 때 사용되며, 이 과정에서 새로운 배열이 만들어 진다.

만약 배열안의 모든 숫자를 제곱해서 새로운 배열로 만들고 싶다면 아래와 같이 map으로 구현할 수 있다.

const array = [1, 2, 3, 4, 5, 6, 7, 8];

const squaredArray = array.map(i => i * i);

console.log(squaredArray);
//[1, 4, 9, 16, 25, 36, 49, 64]

indexOf

원하는 항복이 배열의 몇번째 원소인지를 찾아주는 함수이다. (인덱스를 반환)

const superheroes = ['아이언맨', '캡틴 아메리카', '토르', '닥터 스트레인지'];
const index = superheroes.indexOf('토르');
console.log(index); // 2

findIndex

배열안의 요소가 객체 또는 배열이라면 indexOf대신에 findIndex를 써야한다.

const todos = [
  {
    id: 1,
    text: '자바스크립트 입문',
    done: true
  },
  {
    id: 2,
    text: '함수 배우기',
    done: true
  },
  {
    id: 3,
    text: '객체와 배열 배우기',
    done: true
  },
  {
    id: 4,
    text: '배열 내장함수 배우기',
    done: false
  }
];

예를 들어 다음과 같은 객체 배열이 있을 때, id가 3인 객체가 몇번째 인지 찾으려면

const index = todos.findIndex(todo => todo.id === 3);
console.log(index); // 2

findexIndex를 통해 찾을 수 있다.

find

findfindIndex와 비슷한데, 인덱스를 반환하는 것이아닌 찾아낸 값 자체를 반환한다.

const todo = todos.find(todo => todo.is === 3);
console.log(todo);
// {id: 3, text: "객체와 배열 배우기", done: true}

filter

배열에서 특정 조건을 만족하는 값들만 따로 추출하여 새로운 배열을 만든다.

위 todos배열에서 done값이 false인 항목들만 따로 추출하는 코드는 다음과 같이 작성할 수 있다.

const taskNotDone = todos.filter(todo => !todo.done);

splice

배열에서 인덱스를 활용하여 특정 항목을 제거할 때 사용한다.

주어진 숫자 배열에서 30이라는 요소를 지운다고 해보자

const numbers = [10, 20, 30, 40];
const index = numbers.indexOf(30);
numbers.splice(index, 1);   // index에 해당하는 요소부터 1개요소만 지운다.
console.log(numbers); // [10, 20, 40]

slice

splice와 비슷하지만 다른점은 기존의 배열을 건드리지 않는다는 것이다.

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 , pop

shift는 첫번째 원소를 배열에서 추출한다. (제거 및 반환)

pop은 마지막 뭔소를 배열에서 추출한다. (제거 및 반환)

const numbers = [10, 20, 30, 40];
const valueShfited = numbers.shift();
const valuePoped = numbers.pop();
console.log(valueShifted);    // 10
console.log(valuePoped);      // 40
console.log(numbers);         //[20, 30]

unshift

shift와 반대로 배열의 맨앞에 새 원소를 추가한다.

const numbers = [10, 20, 30, 40];
numbers.unshift(5);
console.log(numbers);    //[5, 10, 20, 30, 40]

concat

여러개의 배열을 하나의 배열로 합쳐준다.

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const concated = arr1.concat(arr2);

console.log(concated); // [1, 2, 3, 4, 5, 6]
console.log(arr1);     // [1, 2, 3]
console.log(arr2);     // [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를 사용하면 다음과 같이 구현할 수 있다.

const numbers = [1, 2, 3, 4, 5];
let sum = array.reduce((accumulator, current) => accumulator + current, 0);

console.log(sum);

reduce함수에는 두개의 파라미터를 전달한다. 첫번째는 accumulator와 current를 파라미터로 가져와서 결과를 반환하는 콜백함수 두번째 파라미터는 reduce함수에서 사용할 초깃값이다.

처음 콜백함수가 호출되어서 0 + 1이 계산되면 이는 그 다음번 호출때 accumulator 값으로 사용된다.

1 + 2 = 3, 3 + 3 = 6, 6 + 4 = 10, 10 + 5 = 15 그래서 결과적으로 15가 리턴이 되는 것이다.

reduce를 사용해서 평균을 계산할 수도 있다.

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);

위 코드의 reduce함수에서 사용한 콜백함수에서는 추가 파라미터로 index와 array를 받아왔는데 index는 현재 처리하고 있는 항목이 몇번째 인지 가르키고, array는 현재 처리하고 있는 배열 자신을 의미한다.

연습 문제

주어진 배열에서 10보다 요소의 갯수를 반환하라

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
function countBiggerThanTen(numbers) {
  let cnt = 0;
  numbers.forEach(function (n) {
    if (n > 10){
      cnt += 1;
    }
  });
  return cnt;
}

const count = countBiggerThanTen([1, 2, 3, 5, 10, 20, 30, 40, 50, 60]);
console.log(count); // 5
function countBiggerThanTen(numbers) {
  return numbers.reduce((acc, current) => {
    if (current > 10) {
      return acc + 1;
    }
    return acc;
  }, 0)
}

const count = countBiggerThanTen([1, 2, 3, 5, 10, 20, 30, 40, 50, 60]);
console.log(count); // 5

프로토타입과 클래스

객체 생성자

객체생성자는 함수를 통해서 새로운 객체를 만들고 그 안에 넣고 싶은 값 혹은 함수들을 구현할 수 있게 해준다.

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();

객체 생성자를 사용할 때는 함수의 이름을 대문자로 시작하고 새로운 객체를 만들때는 new라는 키워드를 앞에 붙여주어야 한다.

같은 객체 생성자 함수를 사용하는 경우, 특정 함수 또는 값을 재사용할 수 있는데 이것이 바로 프로토 타입이다.

프로토타입

프로토타입은 다음과 같이 객체 생성자 함수 아래에 .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

객체 생성자 상속받기

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();

새로만든 Dog와 Cat함수에서 Animal.call을 호출하고 있다. 첫번째 인자에는 this를 넣어 주어야하고, 그 이후에는 Animal객체를 생성하는데 필요한 파라미터들을 넣어 주어야 한다.

추가적으로 prototype을 공유해야 하기 때문에 상속받은 객체 생성자 함수를 만들고 나서 prototype값을 Animal.prototype으로 설정했다.

클래스

ES6부터 추가된 클래스라는 기능으로 객체 생성자로 구현했던 코드를 조금더 명확하고 깔끔하게 구현할 수 있다. 추가적으로 상속도 훨씬 쉽게 구현할 수 있다.

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 cat = new Cat('야옹이', '야옹');

dog.say(); // 멍멍
cat.say(); // 야옹
profile
하루에 한걸음씩, 꾸준히

0개의 댓글