[Front-end] 개발자 공부

[개발 공부 67일차] Debugging & This, Binding, Map과 Set

MOLLY_ 2024. 5. 30. 01:28
728x90

< 목차 >
1. Debugging | TypeError: Cannot set properties of undefined (setting 'toggle')
2. This
3. Binding(바인딩)
4. 고차함수(Higher-Order Function)
5. Map과 Set  개념과 차이
6. API와 메서드의 차이
7. Data Type | 기본형, 참조형
8. 얕은 복사(Shallow Copy)
9. 유사배열객체(Array-like Object)

 

 

1. Debugging | TypeError: Cannot set properties of undefined (setting 'toggle')

 

 

위와 같은 에러가 뜨길래 '엥? 토글 세팅이 뭐가 문제지?' 싶어서 토글 관련 코드를 모두 알아봤다.

 

 

 

 

위처럼 정말 샅샅이 찾아봤는데 문제 될 게 없길래 최신 버전이 아니어서 생긴 문제인가 싶어서 오른쪽 사진처럼 버전도 업데이트했다. 하지만 정답은 아니었다.

 

 

디버깅 성공한 코드

 

 

댓글을 작성했을 때, 토스트 알림이 2번 뜨고 나서 없어지지 않은 채 몇 초가 지나면 뜬 에러라서 설마 Toast 알림을 뜨게끔하는 JSX 코드를 최상단 컴포넌트와 해당 코드가 있는 컴포넌트 둘 다 중복해서 사용해서 그런 것인가? 싶은 생각이 들었다. 그래서 React-toastify JSX 부분을 위와 같이 주석 처리해서 중복 사용 코드를 제거했다.

 

정답이었다. 토스트 컴포넌트가 전역적으로 한 번만 마운트되어야 하는데 중복해서 사용하여 발생한 오류였다. 알아보니 종종 이러한 라이브러리의 문제는 컴포넌트가 중복으로 마운트되거나, 프로젝트의 다른 부분에서 충돌을 일으킬 때 발생한다고 한다. Next 이 자식,,, 왜 오류를 이상하게 알려주는 거야 자꾸

 

 

 

2. This

: 함수가 호출되는 방식에 따라 동적으로 결정

어떻게 호출되는지에 따라 달라지므로, 문맥(context)을 이해하는 것이 중요

 

this를 사용하는 주된 이유는 코드의 문맥(context)에 따라 동적으로 값을 바인딩하여 함수나 메서드가 호출되는 시점에 적절한 객체를 참조할 수 있게 하기 위함이다. 이를 통해 다양한 상황에서 객체의 속성이나 메서드에 접근하고, 재사용 가능한 코드를 작성할 수 있다.

 

 

# this 사용 이유와 이점


1. 전역 문맥 (Global Context)

: 전역 범위에서 `this`는 전역 객체를 참조

  • 브라우저에서는 `window` 객체를, Node.js에서는 `global` 객체를 참조
console.log(this); // 브라우저에서는 window, Node.js에서는 global

 


2. 객체의 속성에 접근 (Object Methods)

: 객체의 메서드 내에서 this를 사용하면 그 객체의 다른 속성에 쉽게 접근 가능

const person = {
  name: 'Alice',
  greet: function() {
    console.log(`Hello, my name is ${this.name}`);
  }
};

person.greet(); // Hello, my name is Alice

 

 

3. 생성자 함수 (Constructor Functions)

: 새로 생성된 인스턴스(객체)의 속성을 설정 가능

function Person(name) {
  this.name = name;
}

const alice = new Person('Alice');
console.log(alice.name); // Alice

 


4. call, apply, bind 메서드
: `call`과 `apply`는 함수를 호출하면서 this를 명시적으로 설정 가능. 즉시 실행

function greet() {
  console.log(this.name);
}

const person = { name: 'Carol' };
greet.call(person); // 'Carol'
greet.apply(person); // 'Carol'



`bind`는 this 값을 설정한 새 함수를 반환한다.

const boundGreet = greet.bind(person);
boundGreet(); // 'Carol'

 

 

5. 콜백 함수에서 컨텍스트 유지

메서드나 함수가 다른 함수에 전달될 때 this를 바인딩하여 컨텍스트 유지 가능

const obj = {
  name: 'Alice',
  greet: function() {
    setTimeout(function() {
      console.log(`Hello, my name is ${this.name}`);
    }.bind(this), 1000); // bind를 사용하여 this를 obj로 설정
  }
};

obj.greet(); // 1초 후에 'Hello, my name is Alice' 출력

 

 

6. 동일한 메서드를 여러 객체에서 재사용

여러 객체에서 같은 메서드를 공유할 때, this를 사용하면 각 객체에 맞게 동작 가능

function greet() {
  console.log(`Hello, my name is ${this.name}`);
}

const person1 = { name: 'Alice', greet: greet };
const person2 = { name: 'Bob', greet: greet };

person1.greet(); // Hello, my name is Alice
person2.greet(); // Hello, my name is Bob

 


7. 화살표 함수 (Arrow Functions)

: 화살표 함수는 자신의 this를 가지지 않으므로 상위 스코프의 this를 사용할 때 유용

const obj = {
  name: 'Alice',
  greet: function() {
    const arrowFunc = () => {
      console.log(`Hello, my name is ${this.name}`);
    };
    arrowFunc();
  }
};

obj.greet(); // Hello, my name is Alice



 

3. Binding(바인딩)

: 프로그래밍에서 변수나 함수와 특정 값을 연결하는 과정

자바스크립트에서 this의 바인딩은 함수가 호출되는 문맥(context)에 따라 this가 참조하는 객체가 결정되는 것

 

 

# this 바인딩은 다섯 가지 주요 방식으로 결정됨

 

1. 전역 바인딩 (Global Binding)
: 전역 문맥에서 this는 전역 객체를 참조함

브라우저 환경에서는 window 객체를, Node.js 환경에서는 global 객체 참조

console.log(this); // 브라우저에서는 window, Node.js에서는 global

 

2. 암시적 바인딩 (Implicit Binding)

: 객체의 메서드로 호출될 때, this는 그 메서드를 소유한 객체를 참조

3. 명시적 바인딩 (Explicit Binding)

: call, apply, bind 메서드를 사용하여 this를 명시적으로 설정 가능

4. new 바인딩 (New Binding)

: 생성자 함수나 클래스의 인스턴스를 생성할 때, this는 새로 생성된 객체 참조

5. 화살표 함수 바인딩 (Arrow Function Binding)

: 화살표 함수는 자신만의 this 바인딩을 가지지 않고, 정의된 위치에서의 상위 스코프의 this를 상속받음

 

 

 

4. 고차함수(Higher-Order Function)

: 다음 2가지 중 하나를 만족하는 함수

  1. 다른 함수를 인자로 받는 함수
  2. 다른 함수를 반환하는 함수

 

1. [예] 다른 함수를 인자로 받는 함수

function higherOrderFunction(callback) {
  callback();
}

function sayHello() {
  console.log('Hello!');
}

higherOrderFunction(sayHello); // 'Hello!' 출력

 

 

2. [예] 다른 함수를 반환하는 함수

function createMultiplier(multiplier) {
  return function (value) {
    return value * multiplier;
  };
}

const double = createMultiplier(2);
console.log(double(5)); // 10 출력

 

 

 

5. Map과 Set  개념과 차이

 

Map

: 키-값 쌍을 저장하는 컬렉션

 

  • 키는 객체를 포함하여 모든 값을 가질 수 있음
  • 순서를 유지하며, 삽입된 순서대로 요소를 반복 가능
  • Data의 구성, 검색, 사용을 효율적으로 처리

 

const map = new Map();

map.set('key1', 'value1');
map.set('key2', 'value2');

console.log(map.get('key1')); // 'value1'

 

 

Set

: 유일한 값을 저장하는 컬렉션

 

  • 값 중복 허용 X
  • 모든 값이 유일하며, 삽입된 순서대로 요소를 반복 가능

 

const set = new Set();

set.add(1);
set.add(2);
set.add(1); // 중복된 값은 무시됨

console.log(set.has(1)); // true
console.log(set.size); // 2

 

 

차이점

  • Map은 키-값 '쌍'을 저장하며, 키는 고유함
  • Set은 '값만' 저장하며, '모든 값이 고유'함

 

 

[Reference]

 

 

6. API와 메서드의 차이

개발에서의 API(Application Programming Interface)와 메서드(Method)는 서로 다른 개념을 의미하지만, 때때로 혼용되는 경우가 있다.

핵심적으로 두 개념의 차이는 다음과 같다.

 

API (Application Programming Interface)

  • 정의: 소프트웨어 애플리케이션 간의 상호 작용을 정의하는 규칙과 프로토콜의 집합
  • 용도: 특정 기능이나 데이터를 외부에서 사용할 수 있도록 제공
  • 구성 요소: 여러 메서드, 엔드포인트, 데이터 형식 등으로 구성됨


메서드 (Method)

  • 정의: 객체나 클래스 내에서 특정 작업을 수행하는 함수
  • 용도: 객체의 상태를 변경하거나 동작을 정의
  • 구성 요소: 함수명, 매개변수, 반환 값 등을 포함

 

혼용되는 경우

  • API의 메서드: 특히 객체 지향 프로그래밍에서, API는 여러 메서드로 구성될 수 있으며, 이 메서드들은 API의 일부분으로 간주된다. 예를 들어, 특정 라이브러리의 API 문서에서 함수나 메서드를 API라고 부르는 경우가 있다.
  • 웹 API: 웹 API에서 특정 HTTP 요청 (예: GET, POST, PUT, DELETE)도 메서드로 언급된다. 이는 API *엔드포인트가 특정 작업을 수행하기 위해 HTTP 메서드를 사용하기 때문이다.

 

예시

// 객체의 메서드
const obj = {
  greet: function(name) {
    return `Hello, ${name}!`;
  }
};

console.log(obj.greet('World')); // "Hello, World!"

// 웹 API 메서드
// GET /users - 사용자 목록 가져오기
// POST /users - 새로운 사용자 생성

 

 

 

*엔드포인트(Endpoint)는 API에서 중요한 개념이다.

 

*엔드포인트(Endpoint)

  • 정의: API가 제공하는 특정 리소스 또는 기능에 접근할 수 있는 URL
  • 구성 요소: 주로 기본 URL, 경로(Path), 및 쿼리 매개변수로 구성됨
  • 용도: 클라이언트가 서버에 요청을 보내고 데이터를 주고받는 데 사용됨

 

[예시] 가상의 API 기본 URL이 https://api.example.com인 경우

 

1. 사용자 목록 가져오기
   - 엔드포인트: https://api.example.com/users
   - HTTP 메서드: GET
   - 설명: 모든 사용자 목록을 반환

 

2. 특정 사용자 정보 가져오기
   - 엔드포인트: https://api.example.com/users/123
   - HTTP 메서드: GET
   - 설명: ID가 123인 사용자의 정보를 반환

 

3. 새로운 사용자 생성
   - 엔드포인트: https://api.example.com/users
   - HTTP 메서드: POST
   - 설명: 새로운 사용자를 생성하기 위해 클라이언트에서 사용자 데이터를 서버로 전송.

 

4. 사용자 정보 업데이트
   - 엔드포인트: https://api.example.com/users/123
   - HTTP 메서드: PUT
   - 설명: ID가 123인 사용자의 정보를 업데이트.

 

5. 사용자 삭제
   - 엔드포인트: https://api.example.com/users/123
   - HTTP 메서드: DELETE
   - 설명: ID가 123인 사용자를 삭제

 

 

 

7. Data Type | 기본형, 참조형

나뉘는 기준은 2가지다. (1) 값 저장 방식, (2) 불변성 여부

 

기본형 (Primitive Types) - 불변성 O

  • Number: 숫자 (정수와 부동 소수점)
  • String: 문자열
  • Boolean: true 또는 false
  • Undefined: 값이 정의되지 않음
  • Null: 의도적으로 비어 있는 값
  • Symbol: 고유하고 변경 불가능한 값
  • BigInt: 큰 정수를 표현하기 위한 값

 

참조형 (Reference Types) - 불변성 X (가변함)

  • Object객체, 배열, 함수 등을 포함하는 타입

 

// 기본형
let number = 42;
let string = "Hello, world!";
let boolean = true;
let undef;
let n = null;
let sym = Symbol('sym');
let bigInt = 123456789012345678901234567890n;

// 참조형
let obj = { name: "Alice" };
let arr = [1, 2, 3];
let func = function() { console.log("Hello!"); };

 

 

 

8. 얕은 복사(Shallow Copy)

: 객체의 참조만 복사하는 방식으로, 원본 객체의 중첩된 객체들까지는 복사하지 않음

즉, 최상위 레벨의 속성들만 복사되고, 중첩된 객체는 원본 객체와 동일한 참조를 가진다.

얕은 복사에서는 중첩된 객체나 배열이 원본과 동일한 참조를 가지기 때문에, 원본이나 복사본 중 하나에서 내부 객체를 변경하면 다른 하나에도 영향을 미친다.

 


예시

const original = { a: 1, b: { c: 2 } };
const copy = { ...original }; // 얕은 복사

copy.b.c = 3;
console.log(original.b.c); // 3 (원본 객체도 변경됨)

 

 

 

9. 유사배열객체(Array-like Object)

: 배열처럼 인덱스로 접근할 수 있고 length 속성을 가지지만, 실제 배열이 아닌 객체
주로 arguments 객체나 DOM 컬렉션이 이에 해당함

 

 

특징

  • 인덱스로 접근 가능: 배열처럼 요소를 인덱스로 접근할 수 있다.
  • length 속성: 요소의 개수를 나타내는 length 속성을 가진다.
  • 배열 메서드 사용 불가: 실제 배열이 아니므로 push, pop 등의 배열 메서드를 직접 사용할 수 없다.
  • 배열로 변환하려면 Array.from()이나 Array.prototype.slice.call()을 사용

 

예시

// arguments 객체는 유사배열객체
function example() {
  console.log(arguments); // { '0': 1, '1': 2, '2': 3 }
  console.log(arguments.length); // 3
  console.log(arguments[0]); // 1
}

example(1, 2, 3);


// 유사배열객체를 배열로 변환
function convertToArray() {
  const argsArray = Array.from(arguments);
  console.log(argsArray); // [1, 2, 3]
}

convertToArray(1, 2, 3);

 

 

728x90