JS 튜토리얼 기본 3부

밍글·2023년 4월 17일
0

JS튜토리얼정리

목록 보기
3/10
post-thumbnail

이번 시간에는 저번 객체파트를 이어서 계속 다룰 예정이고, 자료구조와 자료형에서 헷갈리거나 잘 몰랐던 부분을 절반 정도 다룰예정이다. 전부 다 다루고 싶지만 양이 많을 것 같다는 생각에 다음 파트에 집중적으로 다룰 것 같다😅. 그래도 기초준비를 한다고 생각하고 잘 정리해보도록 하겠다. 그러면 이번 3부를 시작해보도록 하겠다😄


객체

메서드와 this

메서드란 ? 객체 프로퍼티에 할당된 함수

let user = {
  name: "Mingle",
  age: 30
};

user.sayHi = function() {
  alert("안녕하세요!");
};

user.sayHi(); // 안녕하세요!

//혹은 이렇게 해서 진행해도 된다!

user = {
  sayHello() { 
    alert("Hello");
  }
};

user.sayHello(); // Hello

this ? 메서드 내부에서 해당 키워드를 사용하면 객체에 접근할 수 있다

let user = {
  name: "John",
  age: 30,

  sayHi() {
    // 'this'는 '현재 객체'를 나타낸다.
    alert(`${this.name}, Hi!`);
  }

};

user.sayHi(); // John, Hi!

‼️객체에 저장된 정보를 이용하여 문구를 만들고 싶다면 백틱을 이용하여 만들 수 있다‼️
백틱(₩에 위치해있는 곳)으로 전체 문구를 감싸준 다음, 해당 저장된 정보를 ${변수명} 이렇게 담으면 된다.

자유로운 this

자바스크립트의 this는 다른 프로그래밍 언어의 this들과 달리, 모든 함수에 사용할 수 있다.
즉, 자바스크립트에서 this는 런타임에 결정된다. 메서드가 어디서 정의되었는지에 상관없이 this는 ‘점 앞의’ 객체가 무엇인가에 따라 ‘자유롭게’ 결정된다.
다음은 this의 값이 결정되는 경우이다

함수호출방식this값
일반호출전역개체
메서드로서 호출메서드를 호출한 객체
생성자 함수로서 호출생성자 함수가 미래에 생성할 인스턴스

new 연산자와 생성자 함수

생성자 함수 ? 객체를 생성하는 함수, 이렇게 만들어진 객체를 인스턴스라고 한다.

생성자 함수를 생성할 땐 다음과 같은 2가지 조건을 만족해줘야 한다.

1️⃣ 함수 이름의 첫 글자는 대문자로 시작한다.
2️⃣ 반드시 'new' 연산자를 붙여 실행한다.

//해당 함수를 new User로 생성되었을 때 동작되는 알고리즘
function User(name) {
  // 1. this = {};  (빈 객체가 암시적으로 만들어짐)

  // 2. 새로운 프로퍼티를 this에 추가함
  this.name = name;
  this.isAdmin = false;

  // 3. return this;  (this가 암시적으로 반환됨)
}

let user = new User("밍글");
alert(user.name); //밍글

생성자와 return문

생성자 함수엔 보통 return 문이 없다. 반환해야 할 것들은 모두 this에 저장되고, this는 자동으로 반환되기 때문에 반환문을 명시적으로 써 줄 필요가 없다.

⭐️만약에 return문이 있다면 ?
객체를 return 한다면 this 대신 객체가 반환된다.
원시형을 return 한다면 return문이 무시된다.

function User() {

  this.name = "인간";

  return { name: "밍글" };  // <-- this가 아닌 새로운 객체를 반환함
}

alert( new User().name );  // 밍글

생성자 내 메서드

생성자 함수를 사용하면 this에 프로퍼티를 더해주는 것 뿐만 아니라, 메서드를 더해주는 것도 가능하게 된다.

function User(name) {
  this.name = name;

  this.sayHi = function() {
    alert( "내 이름은 " + this.name + "(이)야!" );
  };
}

let mingle = new User("밍글맹글");

mingle.sayHi(); // 내 이름은 밍글맹글(이)야!

옵셔널 체이닝 '?.'

옵셔널 체이닝(optional chaining) ?.을 사용하면 프로퍼티가 없는 중첩 객체를 에러 없이 안전하게 접근할 수 있다.

?.은 ?.'앞’의 평가 대상이 undefined나 null이면 평가를 멈추고 undefined를 반환하게 된다.
⚠️ 다만, ?.는 존재하지 않아도 괜찮은 대상에만 사용해야 한다. 필수로 존재해야 하는거에는 옵셔널 체이닝을 사용하지 않는 걸 권장한다
⚠️ ?.앞의 변수는 꼭 선언되어 있어야 한다.
⚠️ ?.은 읽기나 삭제하기에는 사용할 수 있지만 쓰기에는 사용할 수 없다.
예시 : delete user?.name; ➡️ user가 존재하면 user.name을 삭제한다.

사용예시는 간단한 코드로 보여줄 수 있다.

let user1 = {
  firstName: "Violet"
};

let user2 = null; // user2는 비어있다.

let key = "firstName";

alert( user1?.[key] ); // Violet
alert( user2?.[key] ); // undefined

심볼형

자바스크립트는 객체 프로퍼티 키로 오직 문자형과 심볼형만을 허용한다. 심볼은 유일성이 보장되는 자료형이기 때문에, 설명이 동일한 심볼을 여러 개 만들어도 각 심볼값은 다르다. 심볼에 붙이는 설명(심볼 이름)은 어떤 것에도 영향을 주지 않는 이름표 역할만을 한다.

let id1 = Symbol("id");
let id2 = Symbol("id");

alert(id1 == id2); // false

⚠️ 심볼은 문자형으로 자동 형 변환이 되지 않는다.
심볼에 붙이는 설명을 호출하기 위해서는 symbol.description 프로퍼티를 이용하면 된다.

객체의 ‘숨김’ 프로퍼티 - 외부 스크립트나 라이브러리에 ‘속한’ 객체에 새로운 프로퍼티를 추가해 주고 싶다면 심볼을 만들고, 이를 프로퍼티 키로 사용하면 된다. 외부 스크립트나 라이브러리는 심볼 정보를 갖고 있지 않아서 프로퍼티에 직접 접근하는 것도 불가능하다.

자료구조와 자료형

'null’과 'undefined’를 제외한 원시값에 다양한 메서드를 호출할 수 있다. 원시값에 메서드를 호출하려 하면 임시 객체가 만들어진다.
예시와 동작순서는 다음과 같다.
그리고 원시형의 경우는 전부 다 기입하지 않고 일부 메서드만 다룰 예정이다.

let str = "Hello";

alert( str.toUpperCase() ); // HELLO
/*
1. 원시값의 프로퍼티(toUpperCase)에 접근하는 순간
특별한 객체가 만들어진다. 이 객체는 문자열의 값을 알고 있고, 
toUpperCase()와 같은 유용한 메서드를 가지고 있다.
2. 메서드가 실행되고, 새로운 문자열이 반환된다.
3. 특별한 객체는 파괴되고, 원시값 str만 남게 된다.
*/

isNaN과 isFinite

'==='로 비교를 할 경우, NaN은 자기 자신을 포함하여 그 어떤 값과도 같지 않다는 점에서 false를 반환하는 신기한 현상이 발생한다.😱
alert( NaN === NaN ); // false
그러므로 메서드를 사용하여 테스트하는 것이 좋다.

단항 덧셈 연산자 + 또는 Number()를 사용하여 숫자형으로 변형할 때 사용되는 메서드 ➡️ parseInt와 parseFloat

문자열 관련 메서드

메서드 이름메서드 동작
str.includes(substr)str에 부분 문자열 substr이 있는지에 따라
true나 false를 반환
str.starts(또는 ends)with(sub)문자열 str이 특정 문자열로 시작하는지(start with) 여부와 특정 문자열로 끝나는지(end with) 여부를 확인할 때 사용
str.slice(start [, end])문자열의 start부터 end까지(end는 미포함)를 반환
str.substr(start [, length])start에서부터 시작해 length 개의 글자를 반환

배열과 메서드

🚨배열은 다른 프로그래밍 언어에서도 다루기 때문에 여기서 기초나 메서드를 전부 다 다루지는 않겠다(그럴 경우에는 너무나도 많기 때문이다😅)🚨

큐(queue)는 배열을 사용해 만들 수 있는 대표적인 자료구조이다. push나 shift가 대표적이며 push는 요소를 스택 끝에 집어넣고 shift는 제일 앞 요소를 꺼내 제거한 후 남아있는 요소들을 앞으로 밀어낸다.

배열은 큐 이외에도 스택(stack)이라 불리는 자료구조를 구현할 때도 쓰인다. push나 pop이 대표적이며 그 중, pop은 스택 끝 요소를 추출한다.

스택은 이처럼 '한쪽 끝’에 요소를 더하거나 뺄 수 있게 해주는 자료구조이다.

처음이나 끝에 요소를 더하거나 빼주는 연산을 제공하는 자료구조이기 때문에 이를 데큐라고 부른다. 여기서 안 나온 메서드 중 하나인 unshift는 배열 앞에 요소를 추가한다.

  • 배열은 특별한 종류의 객체이다. 배열 arr의 요소를 arr[0]처럼 대괄호를 사용해 접근하는 방식은 객체 문법에서 왔다. 다만 배열은 키가 숫자라는 점만 다르다.
  • 배열은 참조를 복사한다.(두 변수가 같은 객체를 참조)

배열 관련 메서드 (일부만)

메서드 이름메서드 동작
arr.concat기존 배열의 요소를 사용해
새로운 배열을 만들거나 기존 배열에 요소를 추가한다
arr.forEach주어진 함수를 배열 요소 각각에 대해 실행할 수 있게 해준다.
arr.find(function(item, index, array)true가 반환되면 반복이 멈추고 해당 요소를 반환한다. 조건에 해당하는 요소가 없으면 undefined를 반환한다.
arr.filter(function(item, index, array)조건을 충족하는 요소는 변수에 순차적으로 더해지고, 조건을 충족하는 요소가 하나도 없으면 빈 배열이 반환된다.

너무 많아서 여기다가도 정리하겠습니다.

/*map : 배열 요소 전체를 대상으로 함수를 호출하고,
함수 호출 결과를 배열로 반환한다.*/
let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length);
alert(lengths); // 5,7,6
//정렬 관련
function compareNumeric(a, b) {
  if (a > b) return 1;
  if (a == b) return 0;
  if (a < b) return -1;
}

let arr = [ 1, 2, 15 ];

arr.sort(compareNumeric);

alert(arr);  // 1, 2, 15

//reduce관련 
let value = arr.reduce(function(accumulator, item, index, array) {
  /*
  accumulator – 이전 함수 호출의 결과.
  initial은 함수 최초 호출 시 사용되는 초깃값을 나타냄(옵션)
  item – 현재 배열 요소
  index – 요소의 위치
  array – 배열
  */
}, [initial]);

//reduce 예시
let arr = [1, 2, 3, 4, 5];

// reduce에서 초깃값을 제거함(0이 없음)
let result = arr.reduce((sum, current) => sum + current);

alert( result ); // 15

iterable 객체

반복 가능한(iterable, 이터러블) 객체는 배열을 일반화한 객체이다. 이터러블 이라는 개념을 사용하면 어떤 객체에든 for..of 반복문을 적용할 수 있다. 배열은 대표적인 이터러블이다. 배열 외에도 다수의 내장 객체가 반복 가능하다. 문자열 역시 이터러블의 예시이다.
그 중 문자열과 Array.from의 예시로 보여주도록 하겠다.

Array.from ? 범용 메서드 Array.from는 이터러블이나 유사 배열을 받아 ‘진짜’ Array를 만들어준다. 이 과정을 거치면 이터러블이나 유사 배열에 배열 메서드를 사용할 수 있다.
mapping도 가능하다

for (let char of "test") {
  // 글자 하나당 한 번 실행(4회 호출).
  alert( char ); // t, e, s, t가 차례대로 출력됨
}
//Array.from 예시 
let arrayLike = {
  0: "Hello",
  1: "World",
  length: 2
};

let arr = Array.from(arrayLike); // (*)
alert(arr.pop()); // World (메서드가 제대로 동작!)

Map과 Set

Map

⭐️Map과 객체의 차이점 ?
맵은 키에 다양한 자료형을 허용한다. (객체 포함)
또한 값이 삽입된 순서를 기억한다. (객체는 프로퍼티 순서를 기억하지 못한다.)

Map 사용 예시

let map = new Map();
//map.set(key,value) -> key를 이용해 value를 저장
map.set('1', 'hi');   // 문자형 키
map.set(1, 'hello');     // 숫자형 키
map.set(true, '안녕'); // 불린형 키

// 여기서 차이점 ! 객체는 키를 문자형으로 변환한다.
// 맵은 키의 타입을 변환시키지 않고 그대로 유지한다.
// 따라서 아래의 코드는 출력되는 값이 다르다.
// map.get -> key에 해당하는 값을 반환
// 이 이외에도 has, delete, clear같은 메서드가 있다.
alert( map.get(1)   ); // 'hello'
alert( map.get('1') ); // 'hi'

alert( map.size ); // 3

⭐️체이닝
map.set을 호출할 때마다 맵 자신이 반환되기 때문에 다음과 같이 체이닝을 할 수 있다!

map.set('1', 'str1')
  .set(1, 'num1')
  .set(true, 'bool1');

맵의 요소에 반복 작업하기

map.values(), map.keys(), map.entries() 메서드를 활용하여 맵의 각 요소에 반복 작업이 가능하다.

Set

중복을 허용하지 않는 값을 모아놓은 특별한 컬렉션이다. Set에 키가 없는 값이 저장된다. Set도 반복 작업을 할 수 있다. Set 사용 예시 코드는 아래와 같다.

let set = new Set();

let john = { name: "John" };
let pete = { name: "Pete" };
let mary = { name: "Mary" };

// 어떤 고객(john, mary)은 여러 번 방문하고 있다.
set.add(john);
set.add(pete);
set.add(mary);
set.add(john);
set.add(mary);

// 셋에는 유일무이한 값만 저장
alert( set.size ); // 3

for (let user of set) {
  alert(user.name); // // John, Pete, Mary 순으로 출력
}
profile
예비 초보 개발자의 프로젝트와 공부 기록일지

0개의 댓글