본문 바로가기

공부기록용

[ javascript ] 배열, 함수 기초(~ing)

배열(Array)을 생성할 때 대괄호 기호[]가 사용된다.

배열의 생성 → var fruits = [ '딸기', '포도', '복숭아', '사과' ];

자바스크립트에서는 배열이라는 타입이 없다. console.log(typeof 배열); 이렇게 찍었을 때 object가 찍힌다.

배열은 object타입의 특수한 한 형태이기 때문에 typeof라는 키워드로 객체와 배열을 구분하지 못한다.

Array.isArray()함수를 사용해서 객체와 배열을 구분한다. Array.isArray() 함수의 매개변수로

배열인지를 확인하고 싶은 배열명이나 배열을 전달하면 논리 값에 따라 배열의 여부를 확인할 수 있다.

 

배열의 길이를 확인하고 싶으면 배열을 담고 있는 배열명.length 를 통해 확인할 수 있다.

중요한 점은 배열의 가장 마지막 인덱스의 값은 배열의 길이보다 -1 적다. 배열의 인덱스는 0부터 시작하기 때문

배열의 마지막 인덱스 값: 배열명.length - 1

배열의 마지막 인덱스 다음에 요소를 넣고 싶다면 배열명[배열명.length] = 값; 이렇게 입력해도 된다.

배열 요소를 참조하는 방법 → 배열명[배열에서 참조하고 싶은 값의 인덱스]

예를 들어 var fruits = ['사과', '포도', '복숭아', '참외']; 이렇게 배열이 있을 때

fruits 배열에 저장되어 있는 '포도'를 var grape란 변수에 담고 싶다면

var grape = fruits[1]; 이렇게 작성하면 된다. 해석하자면 fruits란 배열에서 '포도'라는 값이 몇 번째 인덱스에 있느냐를

확인하고 배열명[지목하고 싶은 값의 인덱스] 이렇게 작성하면 된다.

 

배열의 반복문 처리

 

console.log('*************** for 반복문 ***************');
var fruits = ['사과', '포도', '복숭아', '참외'];
for (var i = 0; i < fruits.length; i++) {
  console.log(`${i + 1}. ${fruits[i]}`);
}

console.log('*************** forEach함수 ***************');

fruits.forEach((fruit, index) => {
  console.log(`${index + 1}. ${fruit}`);
});

console.log('*************** while문 ***************');

var whileIndex = 0; // 4
while (whileIndex < fruits.length) {
  // index를 0으로 잡고, 배열의 길이보다 작거나 같을 때까지 블록 내부의 명령문을 수행하기
  console.log(`${whileIndex + 1}. ${fruits[whileIndex]}`);
  whileIndex++;
}

 

- 배열 내부를 전체 순회하여 요소를 하나씩 가져올 수 있는 반복문: for...of문

for( 배열의 요소 받을 변수 of 배열) {

       // 배열의 각 요소가 실행할 명령문

  }

 

- 배열의 각 요소에 지정된 작업을 실행시키고 싶을 때 forEach() 함수를 사용한다. 

 

***for-in은 배열 요소의 모든 index 혹은 객체의 모든 key값에 지정한 명령어를 수행시킬 수 있다.

 

- 배열의 마지막 요소를 제거하고, 제거된 요소를 반환하는 pop() 함수

- 배열의 맨 끝에 요소를 추가하는 함수: push() 추가할 요소를 push() 함수의 매개변수에 전달한다.

- 배열의 맨 첫번째 요소를 제거하고, 제거된 요소를 반환하는 shift() 함수

- 배열의 맨 첫번째 위치에 요소를 추가하는 unshift(), unshift() 함수 매개변수에 추가할 요소를 전달한다.

 

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

 

prompt() 함수를 통해서 사용자로부터 값을 입력받을 때, 사용자가 아무것도 입력하지 않고 엔터를 친다면

''빈 문자열이 반환된다. 취소를 누른다면 null이 반환된다. 빈 공백의 경우 사용자로부터 입력받은 값을 담은 변수의 길이를 측정해서 찍어보니 길이는 측정되나 값은 찍히지 않았다. 빈 공백의 경우 좌우 공백을 모두 없애는 trim() 함수를 사용한 후, 빈 문자열인지를 확인하면 빈 공백을 체크할 수 있을 것 같다.

 

confirm() 함수는 확인과 취소버튼이 있는 메신저 창을 제공한다.

만약 사용자가 메시지를 보고 진짜 확인버튼을 누른다면 true를 반환하고, 취소버튼을 누른다면 false를 반환한다. 

 

배열 실습

var intArray = [];

    while (true) {
      var strNum = prompt('저장할 숫자를 입력해주세요!\n종료를 원하시면 "그만"이라고 작성해주세요!');

      if(strNum.trim() === '그만') 
      {
        if(confirm('정말로 프로그램을 종료하시겠습니까?')) break;
        else continue;
        
      }


      //   !strNum  === (strNum === null) 
      // null 체크와 공백체크, 숫자로 형변환 했을 때 숫자가 아닌지의 여부
      if (strNum === null || strNum.trim() === '' || isNaN(parseInt(strNum))) { // +strNum, Number(strNum)
        alert('유효한 숫자를 입력해주세요!');
        continue;
      }

      var num = Number(strNum);
      intArray.push(num);
      console.log(`배열 요소 타입 ${typeof intArray[0]}`)
    }


    if(!intArray.length) {
      alert('프로그램을 종료합니다.');
    } else {
      var total = 0;
    // 1. intArray.forEach((one) => total += one);

    
    /* 2.
    for(var i = 0; i<intArray.length; i++) {
      
      total += intArray[i];
      console.log(total);
    }*/

    // 3
    for(var number of intArray) {
      total += number;
    }

    alert(`입력한 숫자 총합: ${total},\n입력한 숫자 목록: ${intArray}`);

    }

 

- indexOf() 함수의 매개변수로 값을 전달하면, 값의 유무를 판단하고 → 값이 없다면 -1을 반환한다.

값이 있다면 값이 배열의 어느 인덱스에 존재하는지, 그 인덱스를 반환한다.

 

- 값이 있는지의 유무만 판단하고 싶다면 includes() 함수를 사용한다. includes()는 배열 요소의 존재만 확인한다.

true를 반환한다면 값이 배열에 존재한다는 것, false를 반환한다면 값이 배열에 존재하지 않는다는 것.

 

- slice() 함수는 배열을 잘라서 그 값(들)을 반환한다. slice() 함수의 매개 변수로 잘라낼 배열의 인덱스를 전달한다.

→ 시작 인덱스와 끝 인덱스를 매개 값으로 전달하는데 끝 인덱스는 미만으로 지정하는 것

배열의 몇 번째 인덱스부터 몇 번째 인덱스까지 새로운 배열에 담아서 리턴할 것인지 

마지막 인덱스에 해당하는 값은 포함이 아니라 미만의 의미다.

예를 들어

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

var sliceArr = arr.slice(3, 7);

→ sliceArr에 담긴 값은 3, 4, 5, 6 인데, 인덱스 7은 포함이 아니라 미만의 의미라 인덱스7의 값인 7이 포함되지 않은 것!

slice의 시작을 0부터 끝 인덱스는 지정하지 않는다면 끝까지 범위를 지정하는 것이므로 배열의 요소 전체가 복사된다.

 

- reverse() 함수는 배열을 역순으로 배치한다.

 

- join() 함수는 배열의 요소들을 연결한 문자열로 반환한다.

 

- 배열과 배열을 결합할 때 사용하는 concat() 함수

    // 배열을 결합할 때 사용하는 concat() 함수
    var arr1 = [1, 2, 3, 4, 5];
    var arr2 = [6, 7, 8, 9, 10];
    var concatedArr = arr1.concat(arr2);
    console.log(concatedArr);

 

- splice() 함수는 유용하다, 배열의 특정 요소를 제거한다.

var foods = ['김말이', '떡볶이', '김밥', '닭꼬치', '제육볶음'];

// foods.slice(시작 인덱스, 개수); → 배열의 시작 인덱스부터 개수만큼 지워주고, 지운 요소를 반환한다.

var delFood = foods.slice(1, 2); → foods 배열의 1번 인덱스에 해당하는 요소('떡볶이')부터(count 1개)

count2까지('김밥') 삭제한 뒤 삭제한 요소들을 delFood에 담아서 ['떡볶이', '김밥'] 반환한다.

delFood에 담긴 값들은 ['떡볶이', '김밥'], foods배열에서  '떡볶이', '김밥'이 삭제되어 ['김말이', '닭꼬치', '제육볶음']의 값만 존재하게 된다. 맨 끝에 해당하는 인덱스의 값만 삭제하는 pop() 함수와 맨 앞에 해당하는 인덱스의 값만 삭제하는 unshift() 함수의 단점을 보완하는 slice() 함수

 

splice() 함수는 배열의 요소를 삭제함과 동시에 값을 추가하는 것도 가능하다.

배열의 요소를 삭제하지 않고, 원하는 인덱스에 값을 추가하는 것도 가능하다.

 

splice() 함수를 사용하면서 개수를 지정하지 않으면 시작 인덱스부터 끝까지 삭제된다.배열(명).splice(2); 배열이 갖고 있는 요소의 인덱스 2번부터(2번 포함) 끝 요소의 인덱스까지 모두 삭제한다. 

 

배열 문제 실습

var kakaos = ['무지', '네오', '어피치', '라이언', '제이지'];


// kakaos.length !== 0
while(kakaos.length) {
  var kakao = prompt(`${kakaos.join(', ')} 멤버가 있습니다.\n삭제할 멤버이름을 입력해주세요.`);

  if( !kakao || !kakao.trim() || !kakaos.includes(kakao.trim())) {
    alert('유효한 값을 입력해주세요!');
    continue;
  }

  kakao = kakao.trim();

  if(!confirm(`${kakao}를 정말 삭제하시겠습니까?`)) continue;

  // var idx = kakaos.indexOf(kakao);
  // var delKakao = kakaos.splice(idx, 1);
  kakaos.splice(kakaos.indexOf(kakao), 1);

  alert(`${delKakao}가 삭제되었습니다.`);
}

alert('멤버가 모두 삭제되어 프로그램을 종료합니다.');

 

객체

객체 생성: 클래스 없이 0개 이상의 프로퍼티(property, 속성)로 구성된 집합 자료 구조, 프로퍼티는 키와 값의 쌍으로 구성된다.

객체를 선언할 때는 {}중괄호 기호(배열은 []대괄호 기호)를 사용한다.

var dog = {
	name: '뽀삐',
    kind: '시츄',
    age: 3,
    favorite: ['산책', '간식']
}

// name, kind, age, favorite은 프로퍼티(속성)며, 어떤 값이 담겨있는지를 알 수 있다.

 

객체 프로퍼티를 참조하는 방법 → 객체명.프로퍼티 → 프로퍼티와 쌍을 이루는 값을 알 수 있다.

일반적인 객체 프로퍼티 참조 방법: 객체명.프로퍼티

프로퍼티 참조 다른 방식 → 객체명['키값'] → 객체의 키 값에 해당하는 value를 얻을 수 있다.

객체는 순서가 없다(인덱스가 없다).

 

객체에 프로퍼티를 동적으로 추가하기 → 객체명.새로운 프로퍼티명 = 값;

객체에 존재하는 프로퍼티 삭제하기 → delete 객체명.프로퍼티;

객체의 프로퍼티 키의 존재 유뮤 확인(in 키워드) → 프로퍼티명 in 객체명; 존재하면 true를 반환하고, 존재하지 않으면 false를 반환한다.

 

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

 

객체실습

 

  var userInfo = {
    userList: [{
        account: 'hong9876',
        password: 'kkkk1111',
        username: '김철수'
      },
      {
        account: 'igoigo',
        password: 'ppp4321',
        username: '박영희'
      },
      {
        account: 'psj88',
        password: 'hhh9876',
        username: '홍길동'
      },
    ]
  }

  var users = userInfo.userList;
  while (true) {
    var inputId = prompt('아이디를 입력하세요!');

    if (!inputId || inputId.trim() === '') {
      alert('아이디를 입력하지 않으셨습니다.');
      continue;
    }

    inputId = inputId.trim();

    // 사용자와 입력한 아이디와 일치하는 객체를 담을 변수.
    var foundUser = null;

    for (var user of users) {
      if (inputId === user.account) {
        foundUser = user;
        break;
      }
    } // 반복문이 끝났다. foundUser가 null이라면 id가 존재하는 객체가 없다는 것

    if (foundUser === null) {
      alert('아이디가 존재하지 않습니다!');
      continue;
    }

    while (true) {
      var inputPassword = prompt('비밀번호를 입력하세요!');
      if (!inputPassword || inputPassword.trim() === '') {
        alert('비밀번호를 입력하지 않으셨습니다.');
        continue;
      }

      inputPassword = inputPassword.trim();

      if (inputPassword === fppp4321oundUser.password) {
        alert(`${foundUser.username}님 환영합니다.`);
        break;
      } else {
        alert('비밀번호가 틀렸습니다.');
      }
    }
    break;
  }

 

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

 

함수

반복해서 실행하고자 하는 로직을 코드 블록으로 감싸고, 이름을 붙여서 사용할 때 이름을 호출하는데,

함수를 사용하면 코드가 간결해지고, 생산성이 높아지는 장점이 있다.

***자바스크립트 함수는 매개변수의 개수를 다르게 주더라도 정상 작동한다, 에러가 나지 않는다 → 좋은 코드는 절대 아니다.

 

스프레드 문법 ( ES6문법부터 배열로 감싸지 않아도 스프레드 문법을 사용한다면 여러 개의 값을 매개변수로 전달했을 때, 자동적으로 배열로 감싸준다)

 

// addAll() 함수를 호출할 때 매개변수로 배열을 전달해야 한다.
// []대괄호 기호로 값을 감싸서 전달하거나, 배열 참조변수명을 전달해야 하는데,
// 매개변수에 여러 개의 값을 나열해서 전달하게 되면 에러가 난다.
// 이를 보완하기 위한 스프레드 문법이(ES6) 나왔다.
function addAll(numbers) {
	var total = 0;
    for(var n of total) {
    	total += n;    
    }
    return total;
}

// 스프레드 문법을 이용한 함수
// 변수 앞에 ...을 작성하면 여러 개의 값을 나열해서 전달했을 때
// 여러 개의 값이 자동적으로 배열로 만들어져 함수 내부에 배열로 전달된다.
function addAll(...numbers) {
	var total = 0;
    for(var n of numbers) {
    	total += n;    
    }
    return total;
}