본문 바로가기
항해99/온보딩 스터디

[항해99] 온보딩 스터디 - 5일차 TIL

by junvely 2023. 3. 11.

🦄 온보딩 스터디 5일차 TIL

✨03/06 : 목표 : JS 기초 6파트 객체 공부 


📒강의 노트 정리

01 객체의 기본 

1. 객체 속성과 메소드 차이 

- 속성 : 객체는 key : value => 이름과 값으로 이루어 진다. = 키와 값으로 이루어진 한 쌍의 데이터 자체가 속성 
- 메소드 : 속성 중에서 어떤 동작을 하는 함수 

const object = {
    name: "혼자 공부하는 파이썬", // 속성
    price: 18000,
    publisher: "한빛미디어",
    print(value) { // 메소드 => 속성 중 동작을 하는 함수
      console.log(`${value}를 print 합니다.`);
    },
  };

 

2. 객체의 접근 방법 => 점(.)과 대괄호([]) 

1. 점(.)으로 접근 
- 대부분 *식별자를 키로 사용 => 식별자로 사용할 수 있는 단어
* 식별자로 사용 가능한 경우 : 예약어가 아닌경우, 변수네이밍 규칙과 같은(영문,숫자,$,_)
 
2. 대괄호[' ']로 접근
- 예약어이거나, 식별자로 사용할 수 없는 단어(하이픈, 각종 특수문자열 등)
- 어떤 문자열이 키로 들어올지 예상하지 못할 경우

const object = {    
    "my-color": "blue",
    "my$%#$%@$5": "pink",
}
console.log(object["my-color"]);
console.log(object["my$%#$%@$5"]);

 

3. this 키워드

메서드는 객체에 저장된 정보에 접근할 수 있어야 제 역할을 할 수 있다. 모든 메서드가 그런 건 아니지만, 대부분의 메서드가 객체 프로퍼티의 값을 활용한다.
user.sayHi()의 내부 코드에서 객체 user에 저장된 이름(name)을 이용해 인사말을 만드는 경우가 이런 경우에 속한다.
메서드 내부에서 this 키워드를 사용하면 객체에 접근할 수 있다.
이때 '점 앞’의 this는 객체를 나타낸다. 정확히는 메서드를 호출할 때 사용된 객체를 나타낸다.
let user = {
  name: "John",
  age: 30,

  sayHi() {
    // 'this'는 '현재 객체'를 나타냅니다.
    alert(this.name); // 외부 변수를 참조해 객체에 접근하는 것도 가능하다 => user.name
  }

};

user.sayHi(); // John
- 일반 함수의 this => 암묵적인 this 바운딩을 한다. 자체적으로 알아서 참조할 수 있는 객체를 참조한다.(예측하기 어려움)
=> 객체 내부에서 this를 사용할 경우 this의 상위 스코프 객체를 참조한다. 객체 외부나 함수 안의 함수에서 this를 사용할 경우 참조가 끊기기 때문에 최상위 글로벌 객체인 window를 참조한다. => this 값은 런타임에 결정되며 컨텍스트에 따라 달라진다. 동일한 함수라도 다른 객체에서 호출했다면 'this’가 참조하는 값이 달라진다. 메서드가 어디서 정의되었는지에 상관없이 this는 ‘점 앞의’ 객체가 무엇인가에 따라 ‘자유롭게’ 결정된다.
 

- 화살표 함수의 this 바운딩 => 암묵적 this 바운딩(자유로운, 고유의 객체를 참조하는 등의)을 하지 않는다. 객체 내부에서 사용할 경우 상위 스코프를 참조하여 클래스 등의 메소드에서 상위 객체의 this를 참조하기 위해 많이 사용한다. => 화살표 함수는 일반 함수와는 달리 ‘고유한’ this를 가지지 않는다. 화살표 함수에서 this를 참조하면, 화살표 함수가 아닌 ‘평범한’ 외부 함수에서 this 값을 가져온다. => 예측하기 어렵게 this가 만들어지는 건 원하지 않고, 외부 컨텍스트에 있는 this를 이용하고 싶은 경우 화살표 함수가 유용하다.

*this 바운딩 => 'this는 항상 메서드가 정의된 객체를 참조한다' 라는 개념 => 다른 언어에서는 this 바운딩 되지만, 자바스크립트에서는 그렇지 않아(암묵적 this 바운딩) 혼동

- this 정리

  • this 값은 런타임에 결정된다.
  • 함수를 선언할 때 this를 사용할 수 있다. 다만, 함수가 호출되기 전까지 this엔 값이 할당되지 않는다.
  • 함수를 복사해 객체 간 전달할 수 있다.
  • 함수를 객체 프로퍼티에 저장해 object.method()같이 ‘메서드’ 형태로 호출하면 this는 object를 참조한다.
  • 화살표 함수는 자신만의 this를 가지지 않는다는 점에서 독특하다. 화살표 함수 안에서 this를 사용하면, 외부에서 this 값을 가져온다.

 

4. 메소드 간단 선언 구문 => 익명함수 간단하게 선언 가능

print: function(value){
        console.log(`${value}를 print 합니다.`)
    }
// 익명함수 => 간단하게 선언
print(value) {
      console.log(`${value}를 print 합니다.`);
    },

 

 

5. 생성자 함수

- 생성자 함수(짧게 줄여서 생성자)는 일반 함수다. 다만, 일반 함수와 구분하기 위해 함수 이름 첫 글자를 대문자로 쓴다. => class와 같다.

- 생성자 함수는 반드시 new 연산자와 함께 호출해야 한다. new와 함께 호출하면 내부에서 this가 암시적으로 만들어지고, 마지막엔 this가 반환된다.

- 생성자 함수는 유사한 객체를 여러 개 만들 때 유용하다.
 
- 자바스크립트는 언어 차원에서 다양한 생성자 함수를 제공한다. 날짜를 나타내는 데 쓰이는 Date, 집합(set)을 나타내는 데 쓰이는 Set, Map 등의 내장 객체는 이런 생성자 함수를 이용해 만들 수 있다. 
function User(name) {
  this.name = name;

  this.sayHi = function() {
    alert( "제 이름은 " + this.name + "입니다." );
  };
}

let bora = new User("이보라");

bora.sayHi(); // 제 이름은 이보라입니다.

 

6. 순회에 필요한 메소드 => map.keys(), map.values(), map.entries()

  • Map
  • Set
  • Array  에서만 사용 가능하다.

1) 객체에서 순회

- Object.keys(obj) – 객체의 키만 담은 배열을 반환한다.
- Object.values(obj) – 객체의 값만 담은 배열을 반환한다.
- Object.entries(obj) – – [키, 값] 쌍을 담은 배열을 반환한다
 
let user = {
  name: "Violet",
  age: 30
};

// 값을 순회합니다.
for (let value of Object.values(user)) {
  alert(value); // Violet과 30이 연속적으로 출력됨
}
2) 객체 변환하기 => 객체에서 map등의 메소드 사용하는 방법
 
객체엔 map, filter 같은 배열 전용 메서드를 사용할 수 없다. 하지만 Object.entriesObject.fromEntries를 순차적으로 적용하면 객체에도 배열 전용 메서드 사용할 수 있다. 적용 방법은 다음과 같다.
 
  • Object.entries(obj)를 사용해 객체의 키-값 쌍이 요소인 배열을 얻는다.
  • 만든 배열에 map 등의 배열 전용 메서드를 적용한다.
  • 반환된 배열에 Object.fromEntries(array)를 적용해 배열을 다시 객체로 되돌린다.
 
let prices = {
  banana: 1,
  orange: 2,
  meat: 4,
};

let doublePrices = Object.fromEntries(
  // 객체를 배열로 변환해서 배열 전용 메서드인 map을 적용하고 fromEntries를 사용해 배열을 다시 객체로 되돌립니다.
  Object.entries(prices).map(([key, value]) => [key, value * 2])
);

alert(doublePrices.meat); // 8
 


 
 

02 객체의 속성과 메소드 사용하기 

1. 기본(primitive타입) 자료형을 제외한 모든 자료형은 속성을 가질 수 있다. => 배열, 함수 

  const a = [];
  a.sample = 10;
  console.log(a.sample);
  a.gana = 2;
  console.log(a); //[ sample: 10, gana: 2 ]

  const b = function () {};
  b.sample = 10;
  b.gana = 2;

  console.log(b);
  console.log(typeof b); //{ sample: 10, gana: 2 }

- 배열이나 함수에서도 속성 추가가 가능하다.(실무에서는 잘 사용하지 않는다.)
 

2. 기본 자료형을 객체로 선언하기(Number, String, Boolean)

- *String이나 Number 등은 primitive타입 기본 자료형인데, 객체가 아닌데도 어떻게 속성과 메소드를 사용할 수 있을까?
=> 자바스크립트는 기본 자료형의 속성과 메소드를 호출할 때 일시적으로 기본 자료형을 객체로 승급시킨다. 그래서 속성과 메소드를 사용할 수 있다. 이러한 승급은 일시적이다. 따라서 기본 자료형에 속성을 추가하면 추가되는 것 처럼 보이지만 실제로는 추가되지 않는다. => 문장 종료 후 바로 승급 해제 

const a = new Number(273);
  a.sample = "hi";
  console.log(a.sample);

  a.method1 = function () {
    console.log("안녕하세요");
  };
  a.method1();

 

3. 프로토타입으로 메소드 추가하기

- 어떤 객체의 prototype이라는 속성이 바로 객체의 전용 틀이라고 할 수 있다. prototype객체에 속성과 메소드를 추가하면 모든 객체(기본 자료형에서도)에서 해당 속성과 메소드를 사용할 수 있다.
ex) 숫자 객체 전체에 어떤 속성과 메소드를 추가할 수 있다면 숫자 타입도 숫자 속성과 메소드를 사용할 수 있다.
1) 어떤 객체 자료형에 prototype 추가하기 => Number에 prototype을 추가하면, 숫자 기본 자료형에서 해당 메소드를 사용할 수 있다.(일반적으로는 모든 숫자 자료형이 어떤값을 공유할 필요는 없기때문에 속성 추가x 실무에서는 잘 사용하지 않는다.)

Number.prototype.sample = 10

const i = 273
i.smaple // 10

2) 기본 자료형 변수를 객체로 변경해 속성 추가 / 기본 자료형 타입 자체에 속성 추가

// 1. 기본 자료형을 객체로 변경하여 속성과 메소드 추가하기
const num = new Number(52000);
  num.sample = 10; //속성
  //메소드
  num.method1 = function () {
    return this.valueOf() + "원";
  };

  console.log(num.sample); // 10
  console.log(num.method1()); // 52000원

// 2. 기본 자료형 타입 자체에 속성이나 메소드 추가하기
  Number.prototype.sample = function () {
    return this.valueOf() + "원";
  };

  const num2 = 30;
  console.log(num2.sample()); // 30원

 
- this에서 객체 내부의 값을 꺼내 쓰는 것임을 명확하게 하기 위해서는 valueOf() 메소드를 사용한다.
- 문자열.indexOf(''), 배열.indexOf('') => 해당 문자의 시작 index를 반환한다.
 

4. Number 객체 메소드

.toFixed(자리수) : 소수점 이하 자리수까지만 출
.isNaN() : NaN인지 확인
.isFinite() : Infinity인지 확인
 

5. String 객체 메소드

.trim() : 앞뒤 공백(띄어쓰기, 줄바꿈) 제거
.split() : 문자열을 매개변수 문자로 잘라서 배열을 만들어 리턴

input = string.split('/n') // 줄바꿈 기준으로 나뉨
input = input.map((line) => line.split(','))
//[[1, 2, 3, 4 ], [ ], [ ], [ ], ... ] 배열 안의 배열들로 반환

 
 

6. JSON 객체

- 자바스크립트가 기본적으로 제공하는 내장 객체 => 자바스크립트의 배열과 객체를 활용해 객체처럼 자료를 표현하는 방식 => 데이터를 주고 받을 때의 데이터 포맷
- JSON 형식 규칙)

  • 값을 표현할 때는 문자열, 숫자, 불 자료형만 사용할 수 있다(함수 등 사용불가)
  • 문자열 반드시 큰따옴표로 만들어야 한다.
  •  key에도 반드시 따옴표를 붙여야 한다.
  • 대부분 프로그래밍 언어는 JSON형식 문자열을 읽는 기능이 있다. 그래서 데이터 교환 시 마다 활용하여 읽는다. 자바스크립트 객체를 JSON 문자열로 변환할 때는 JSON.stringify() 메소드를 사용한다.

 
1. JSON.stringify() 메소드 사용해 보기

결과 확인 )

 
2. JSON.parse() => JSON 문자열을 자바스크립트 객체로 전개할 때는 JSON.parse() 메소드를 사용한다.

결과 확인)

- JSON을 활용한 깊은 복사 => JSON.stringify()로 어떤 Object를 JSON 문자열로 변환시키면, 해당 객체가 JSON문자열 타입으로 새로 생성되어 메모리에 할당 되고, 변환된 문자열을 다시 JSON.parse()하여 다시 자바스크립트 Object로 변환하게 되면, 새로 생성된 JSON문자열이 새로운 자바스크립트 객체로 변환된다.(문자열로써 새 메모리에 할당되었기 때문에 참조 관계가 끊긴다.)
 

7. Math함수

Math.random() => 0~1까지의 랜덤 숫자 생성
 
 

03 객체와 배열 고급

1. 배열 기반의 다중 할당(구조 분해 할당)

[ 식별자, 식별자, 식별자 ... ] = 배열
const array = [1, 2, 3, 4, 5]; 
const [a, b, c] = array; 
console.log(a, b, c); //1 2 3 

//활용 
function userInfo(...array) {
	const [name, age, color] = array; 
	console.log(`내 이름은 ${name}이고 ${age}살이야.`); 
} 
userInfo("준영", 27, "pink");

 

 

2. 객체 기반의 다중 할당(구조 분해 할당)

{속성 이름, 속성 이름} = 객체
{식별자 = 속성 이름, 식별자 = 속성 이름} = 객체
const { name, price, myColor } = object;
console.log(name, price, myColor);
const { a = name, b = price, c = myColor } = object;
console.log(a, b, c);
let options = {
  title: "Menu",
  height: 200,
  width: 100
};

// title = 이름이 title인 프로퍼티
// rest = 나머지 프로퍼티들
let {title, ...rest} = options;

// title엔 "Menu", rest엔 {height: 200, width: 100}이 할당됩니다.
alert(rest.height);  // 200
alert(rest.width);   // 100

 

3. 여러 가지 구조 분해 할당 => 모든 iterable, 반복 가능한 객체에 구조 분해 할당을 적용할 수 있다.

// 문자열도 가능
let [a, b, c] = "abc"; // ["a", "b", "c"]
let [one, two, three] = new Set([1, 2, 3]);
//활용2
let [firstName, surname] = "Bora Lee".split(' ');
// 활용3 => 필요없는 부분 버릴 수 있음
// 두 번째 요소는 필요하지 않음
let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];

alert( title ); // Consul
let options = {
  title: "My menu",
  items: ["Item1", "Item2"]
};

function showMenu({
  title = "Untitled",
  width: w = 100,  // width는 w에,
  height: h = 200, // height는 h에,
  items: [item1, item2] // items의 첫 번째 요소는 item1에, 두 번째 요소는 item2에 할당함
}) {
  alert( `${title} ${w} ${h}` ); // My Menu 100 200
  alert( item1 ); // Item1
  alert( item2 ); // Item2
}

showMenu(options);

 

4. 스프레드(...) 전개 연산자 => 배열, 객체 => 깊은 복사

- 스프레드(...)연산자를 이용한 복사는 1차원 배열이나 객체까지만 깊은 복사가 가능하다. 2차원 배열이나 객체를 깊은 복사 하고 싶다면, for문 등으로 반복문을 사용하여 복사도 가능하다.

//배열
[...] 또는
[... array, a, b, c] // clone => 깊은 복사 새 배열에 복사, 하지만 1차원 배열까지만 깊은 복사

//객체
{...}
{...object, a, b, c} // clone => 깊은 복사 새 배열에 복사, 하지만 1차원 객체까지만 깊은 복사

 
 

✅ 배운 점

시간이 너무 빠르게 가는 것 같다. 공부한지 벌써 5일차다..오늘은 자바스크립트의 가장 중요한 개념 중 하나인 객체에 대해 배웠다.

1. 객체 생성방법
2. 객체 접근방법
3. 동적 객체 추가/삭제
4. 메소드 간단 선언
5. JSON 객체
6. MATH 객체
7. 배열 객체 다중할당
8. 스프레드 연산자(전개 연산자)

공부할 부분이 가장 많은 파트이기도 해서 공부하면서 처음 보는 내용도 많았던 것 같다. 1. primitive타입에서 속성이나 메소드를 사용할 수 있는 이유라던지, 2. prototype을 이용해 객체에 메소드를 생성할 수 있다는 것 이라던지.. 현재는 class가 존재 하기 때문에 실제로 사용되진 않을 것 같지만 과거에는 class extends 대신 객체를 생성하고 어떤 메소드 등을 공통적으로 상속하여 사용하기 위해 많이 사용했을 것 같다. 
가장 헷갈렸던 부분은 3. this바운딩과 깊은복사,얕은복사에 대한 개념이었다. this 바운딩은 정말 깊이 공부해 봐야 알 것 같다. 기술매니저님께서는 실행컨텍스트나 스코프 관련하여 공부해 보아야 더 깊은 내용을 이해할 수 있을 것이라고 하셨다. 앞으로 계속 보면서 생각해 봐야 할 과제인 것 같다.
항상 4. 스프레드 연산자(...)를 사용하면서 들었던 생각이 그래서 이건 과연 깊은 복사일까? 얕은 복사일까?라는 의문이었다.하나하나 값을 비교해보고 복사한 값을 변경하면서 깨달은건 깊은 복사가 맞다. 복사한 값을 변경하여도 아예 새로운 배열로 생성되어 참조가 끊겨 기존 값이 변경되지 않았다. 하지만 1차원 배열이나 객체 까지만 복사가 가능하다. 기술 매니저님께 여쭤보니 for문을 통해 2차원 배열이나 객체까지 복사할 수 있다는 것을 새로 알았다. 
 
 

보완할 점

더 공부하고 싶은 부분 : this 바운딩, JSON, 깊은 복사와 얕은 복사, 실행컨텍스트와 스코프 관련해서 공부