[JS/Node] 객체 지향 JavaScript

LEE JI YOUNG·2021년 12월 13일
0

JS/Node

목록 보기
10/23
post-thumbnail

Achievement Goals

  • 클래스와 인스턴스라는 용어를 이해할 수 있다.
    • new 키워드의 사용법을 이해할 수 있다.
    • class 키워드의 사용법을 이해할 수 있다.
    • 현실 세계의 모델을 바탕으로 클래스의 메소드와 속성을 디자인할 수 있다.
  • 객체 지향 프로그래밍 특징을 이해할 수 있다.
    • 캡슐화
    • 상속
    • 추상화
    • 다형성
  • JavaScript에서 객체 지향 프로그래밍을 구현할 수 있다.
    • Prototype이 무엇인지 이해할 수 있다.
  • 객체 지향 프로그래밍의 상속(Inheritance)의 개념을 이해하고 코드로 작성할 수 있다.
    • 상속관계를 가진 현실 세계의 모델을 코드로 작성할 수 있다.
    • 클래스 상속의 원리를 이해할 수 있다.
    • Prototype chain을 이해하고 설명할 수 있다. (__proto__)

Read Me

  • 객체 지향 프로그래밍(OOP, Object-oriented programming)

    • 절차 지향 프로그래밍과는 다르게 데이터와 기능을 한 곳에 묶어서 처리
    • 속성과 메소드가 하나의 "객체"라는 개념에 포함
    • 자바스크립트 내장 타입인 object(이하, object literal)와는 다르게, 클래스(Class)라는 이름으로 부릅니다.
    • 객체 지향 프로그래밍은 사람이 세계를 보고 이해하는 방법과 매우 흡사. 코드를 추상화하여 직관적으로 생각 가능. 이미 오래 전부터 프로그래밍 방법론으로 매우 빠르게 적용 됨.
  • 객체 지향 프로그래밍을 철저하게 적용한 프로그래밍 언어 : Java, C#

  • 자바스크립트에서 OOP를 구현하는 방법은 조금 독특

  • 이번 유닛에서는 자바스크립트로 직접 객체 지향 프로그래밍을 구현하며, 객체 지향 프로그래밍의 장점과 각종 용어들을 이해합니다.


클래스를 이용한 모듈화

메소드 호출 실습하기

var elements = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
];

// 이 문장은 배열을 반환함: [8, 6, 7, 9]
elements.map(function(element) {
  return element.length;
});

// 위의 일반적인 함수 표현은 아래 화살표 함수로 쓸 수 있다.
elements.map((element) => {
  return element.length;
}); // [8, 6, 7, 9]

// 파라미터가 하나만 있을 때는 주변 괄호를 생략할 수 있다.
elements.map(element => {
  return element.length;
}); // [8, 6, 7, 9]

// 화살표 함수의 유일한 문장이 'return'일 때 'return'과
// 중괄호({})를 생략할 수 있다.
elements.map(element => element.length); // [8, 6, 7, 9]

// 이 경우 length 속성만 필요하므로 destructuring 매개변수를 사용할 수 있다.
// 'length'는 우리가 얻고자 하는 속성에 해당하는 반면,
// lengthFooBArX'는 변경 가능한 변수의 이름일 뿐이므로
// 원하는 유효한 변수명으로 변경할 수 있다.

// 내 설명 :: { length: lengthFooBArX } = el 인데 구조분해로 
//({}의 length 키의 값)lengthFooBArX  = (el의 length 키의 값)el.length 이 된다. 
elements.map(({ length: lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]

// destructuring 파라미터 할당도 아래와 같이 작성할 수 있습니다.
// 이 예에서 정의한 객체내의 'length'에 값을 지정하지 않은 점에 주목하세요. 
// 대신, "length" 변수의 리터럴 이름은 우리가 해당 객체에서 꺼내오고 싶은 
// 속성이름 자체로 사용됩니다.

// 내 설명 :: 객체 구조 분해에서  var {p, q} = {p: 42, q: true}; 이면
// console.log(p); // 42 이다. 
// 따라서 { length } = el의 {length: ~~} = el.length 이다.
elements.map(({ length }) => length); // [8, 6, 7, 9] 

메소드 호출 - Singleton 패턴

  • 객체.메소드()
  • 단 하나의 객체만 만들 수 있다. 재사용성 떨어짐.
  • !!메소드 호출 방식을 이용할 때에는 화살표 함수를 쓰지 않습니다.!!
    : 화살표 함수는 자신의 this가 없다. 화살표 함수는 바인딩하지 않은 this. 대신 화살표 함수를 둘러싸는 렉시컬 범위(lexical scope)의 this가 사용된다; 화살표 함수는 일반 변수 조회 규칙(normal variable lookup rules)을 따르기 때문에 현재 범위에서 존재하지 않는 this를 찾을 때, 화살표 함수는 바로 바깥 범위에서 this를 찾는것으로 검색을 한다.
  • Lexical scope : 함수를 어디서 선언하였는지에 따라 상위 스코프를 결정하는 것
  • 화살표함수
let counter1 = {
  value: 0,
  increase: function() {
  	this.value++ // 메소드 호출을 할경우, this는 counter1을 가리킴.
  },
  decrease: fuction() {
	this.value--
  },
  getValue: function() {
    return this.value
  }
} 
counter1.increase()
counter1.increase()
counter1.increase()
counter1.decrease()
counter1.getValue() // 2

클로저를 이용해 매번 새로운 객체 생성하기

클로저 모듈 패턴

  • 코드 복사 붙여넣기 없이, 똑같은 기능을 하는 counter1을 여러개 만들 수 있다.
  • 클로저는 독립적인 변수를 가리키는 함수이다. 또는, 클로저 안에 정의된 함수는 만들어진 환경을 기억한다.
function makeCounter() {
  return {
    value: 0,
    increase: function() {
      this.value++ // 메소드 호출을 할 경우, this는 makeCounter 함수가 리턴하는 익명의 객체입니다
    },
    decrease: function() {
      this.value--
    },
    getValue: function() {
      return this.value;
    }
  }
}

let counter1 = makeCounter()
counter1.increase()
counter1.getValue() // 1

let counter2 = makeCounter()
counter2.decrease()
counter2.decrease()
counter2.getValue() // -2

OOP 패턴(class 문법을 이용)으로 구현한 counter 예시

class Counter {
  constructor() {
    this.value = 0; // 생성자 호출을 할 경우, this는 new 키워드로 생성한 Counter의 인스턴스입니다
  }
  increase() {
    this.value++
  }
  decrease() {
    this.value--
  }
  getValue() {
    return this.value
  }
}

let counter1 = new Counter() // 생성자 호출
counter1.increase()
counter1.getValue() // 1

클래스와 인스턴스

객체 지향 프로그래밍

: 하나의 모델이 되는 청사진(blueprint)을 만들고, 그 청사진을 바탕으로 한 객체(object)를 만드는 프로그래밍 패턴

  • 청사진 => class (생성자(constructor) 함수)
    : ex ) Car
    • 인스턴스가 만들어질 때 실행되는 코드. 속성과 메소드를 정의한다.

      • 속성 : 변수. 새로운 인스턴스 생성시 고유한 값을 부여.
      • 메소드 : 객체에 딸린 함수.
    • (ES5 : 함수) 일반적인 함수를 정의하듯 만든다.
      :function Car(color) { //인스턴스가 만들어질 때 실행되는 코드}

    • (ES6 : 생성자(constructor) 함수) : class, constructor 이용
      :class Car { constructor(color){//인스턴스가 만들어질 때 실행되는 코드 } }

  • 청사진을 바탕으로 한 객체 => instance (인스턴스, instance object, 인스턴스 객체)
    : ex ) Avante, Mini, Beetles
    • let avante = new Car('blue');
      • 함수를 이용하는 방법은 새로운 인스턴스를 만든다.
      • 각각의 인스턴스는 Car라는 클래스의 고유한 속성과, 메소드를 갖는다.
      • 클래스에 속성과 메소드를 정의하고 인스턴스에서 이용.
  • 클래스를 일반적인 다른 함수와 어떻게 구분?
    • 클래스 : 대문자, 그리고 일반명사 ( 클래스를 만드는 암묵적인 규칙 )
    • 일반적인 함수 : 적절한 동사를 포함하고, 소문자로 시작하기

ES5와 ES6의 차이

: 객체지향 프로그래밍에서 생성자(constructor) 함수라고 불림. class 키워드 사용.

  • ES5 : 클래스는 함수로 정의
function Car(brand, name, color){
	// 인스턴스가 만들어질 때 실행되는 코드
}
  • ES6 : class라는 키워드를 이용해서 정의할 수도 있다.
class Car{
	constructor(brand, name, color){
    // 인스턴스가 만들어질 때 실행되는 코드
      // - class : 속성의 정의 
      // - this:인스턴스 객체를 의미. this에 할당한다는 것은, 
      // 만들어진 인스턴스에 해당 브랜드, 이름, 색상을 부여하겠다는 의미
      // - parameter : 브랜드, 이름, 색상 등은 인스턴스 생성시 지정하는 값 
      this.brand = brand;
      this.name = name;
      this.color = color;
    }
    // 메소드 정의 : 
      refuel(){}  
      drive(){}
    }
}

let avante = new Car ('hyundai', 'avante', 'black');
avante.color ; //black
avante.drive(); // 아반떼가 운전을 시작합니다.
// - 인스턴스는(let avante) Car라는 클래스의 고유한 속성과 메소드를 갖는다.
// - 인스턴스를 만들 때에는 new 키워드를 사용. -> 즉시 생성자 함수가 실행되며, 
// 변수에 클래스의 설계를 꼭 닮은 새로운 객체, 즉 인스턴스가 할당.

자바스크립트 용어

  • prototype : 모델의 청사진을 만들 때 쓰는 원형 객체(original form)입니다.
  • construtor : 인스턴스가 초기화될 때 생성자 함수.
  • this : 함수가 실행될 때, 해당 scope마다 생성되는 고유한 실행 context(execution context)new 키워드로 인스턴스를 생성했을 때에는, 해당 인스턴스가 바로 this의 값이 됨.

  • Array 는 인스턴스이다.


Prototype

  • 절차적 언어 : 순차적인 명령의 조합. 초기의 프로그래밍 언어. (C, 포트란 등). 함수로 이동하는 방식. 변수와 함수를 별개로 순차적으로 작동하는 단순한 방식.
  • 객체 지향 언어 : 클래스라고 부르는 데이터 모델의 청사진을 사용해 코드 작성. 현대 언어들은 대부분 객체 지향의 특징을 가짐. (대표적으로 Java, C++, C# 등).
    • JavaScript: 엄밀히 말해 객체 지향 언어는 아니지만, 객체 지향 패턴으로 작성 가능 하다.
    • 객체 지향 프로그래밍 특징 : 데이터의 접근과, 데이터의 처리 과정에 대한 모형을 만들어 내는 방식을 고안. 데이터와 기능을 한번에 묶어서 처리 가능하게 됨. 빠르게 현대 언어에 적용 됨.
    • 객체 내에는 "데이터와 기능이 함께 있다"는 원칙에 따라 메소드와 속성이 존재

객체 지향 프로그래밍 (Object Oriented Programming : OOP)

  • OOP는 프로그램 설계 철학.

  • OOP의 모든 것은 "객체"로 그룹화 됨.

  • OOP의 4가지 주요 개념을 통해 재사용 가능.
    : 이 객체는 한번 만들고 나면, 메모리상에서 반환되기 전까지 객체 내의 모든 것이 유지.

    • 데이터와 기능이 함께 있다 : 객체 내에는 메소드와 속성이 존재.

      • 예 ) 모든 자동차는 공통적인 기능과 고유의 속성
        -> 모든 자동차 :
        - 자동차 기능 : 주행 속도, 주유, 전진, 후진 /
        - 자동차 고유의 속성(고유데이터) : 색상, 최고 속력, 탑승인원, 가격
        -> 새로운 객체(자동차) 생성 : "이번에 만들 자동차는, 빨간색의 최고 속력은 200km/h 를 내도록 만들어보자!"와 같이, 속성에 고유한 값을 부여할 수 있습니다.

클래스와 인스턴스

  • 클래스 : 일종의 원형(original form)으로, 객체를 생성하기 위한 아이디어나 청사진. 세부사항이 들어가지 않은 것.

    • 메소드
  • 생성자(constructor) : 클래스는 객체를 만들기 위한 생성자(constructor)함수를 포함.
    생성자를 통해 세부 사항(속성) 을 넣어줌. 함수에 인자를 넣듯, 속성을 넣는다.

    • 속성
  • 인스턴스 : 클래스의 사례(instance object). 클래스를 통해 만들어진 객체.


OOP Basic Concepts

: 애플리케이션을 만들 때 좋은 설계를 하기 위해서는, 기본적으로 이 객체지향을 이해하고 응용하는 것이 중요. 객체 지향 프로그래밍의 4가지 기본적 컨셉

1. Encapsulation (캡슐화)
: 데이터(속성)와 기능(메소드)을 하나의 단위(하나의 객체)로 묶는 것

  • 캡슐화 특징 :

    • 은닉화(hiding) : 구현은 숨기고, 동작은 노출시킴. 디테일한 구현(내부 데이터나 내부 구현)이나 데이터는 숨기고, 객체 외부에서 필요한 동작(메소드)만 노출. 은닉화의 특징을 살려서 코드를 작성하면 객체 내 메소드의 구현만 수정하고, 노출된 메소드를 사용하는 코드 흐름은 바뀌지 않도록 만드는 것이 가능. 더 엄격한 클래스는 속성의 직접적인 접근을 막고, 설정하는 함수(setter), 불러오는 함수(getter)를 철저하게 나누기도 한다.

      • Getters와 Setters
      • 절차적 코드 : 데이터의 형태가 바뀔 때에 코드의 흐름에 큰 영향을 미치게 되어 유지보수가 어렵다.
    • 느슨한 결합(Loose Coupling) 에 유리: 언제든 구현을 수정할 수 있음 . 코드 실행 순서에 따라 절차적으로 코드를 작성하는 것이 아니라, 코드가 상징하는 실제 모습과 닮게 코드를 모아 결합하는 것을 의미. 느슨한 결합을 추구하는 코드 작성법은 코드만 보고도 인스턴스 객체의 기능을 상상할 수 있게 작성하는 것.

  • 캡슐화와 은닉화의 차이점
    : 속성의 접근을 제어 하는 것을 은닉화, 메서드의 내부를 알지 못하도록 하는 것을 캡슐화.

    • 은닉화 : 외부에서 객체의 속성을 함부로 접근하지 못하도록 하는 것. 중요사항이(변수든 메소드든 간에) 밖으로 드러나지 않도록 꼭꼭 감추는것.

    • 캡슐화 : 메서드 안에서 어떠한 일이 일어나고 있는지 모르게 해야한다는 것. 중요사항을 감춘 상태에서 외부에 그것을 사용할수 있는 방법을 설정하고 외부와 직접적으로 의사소통을 의미.


2. Inheritance (상속)
: 상속은 부모 클래스의 특징을 자식 클래스가 물려받는 것. "기본 클래스(base class)의 특징을 파생 클래스(derive class)가 상속받는다"

  • 예 )
    • 클래스 : 사람(Human)
      • 사람 속성 : 이름, 성별, 나이 / 메소드 : 먹다, 자다
    • 클래스 : 학생(Student)
      - 사람(Human) 클래스의 속성과 메소드를 재구현(비효율적)하지 않음. 학생의 본질은 결국 사람이므로, 상속을 이용하여 학생(Student) 클래스는 사람(Human)클래스를 상속 받는다.
      - 사람 클래스에 속성, 메소드 추가 :: 학생 속성 : 학습 내용 / 학생 메소드 : 공부하다

3. Abstraction (추상화)
: 내부 구현은 아주 복잡한데, 실제로 노출되는 부분은 단순하게 만든다는 개념. 밖에 나온 부분인 인터페이스만 접근할 줄 알면 된다.


  • 예 ) 전화라는 객체가 있다면, 그 안에는 스피커와 마이크가 존재하고, 서킷 보드 등이 존재하는 등 내부 구현이 되어있다. 실제로 사용할 때에는, 이러한 존재에 대해서는 생각하지 않고 단순히 수화기를 들고 버튼을 눌러서 해결하는 것으로 인터페이스(interface)를 단순화 가능하다.

  • 추상화를 통해 인터페이스가 단순해짐. 너무 많은 기능들이 노출되지 않아서 예상치 못한 사용상의 변화가 일어나지 않도록 만들 수 있음.

  • 추상화와 캡슐화 비교

    • 캡슐화 : 코드나 데이터의 은닉에 포커스.
    • 추상화 : 클래스를 사용하는 사람이 필요하지 않은 메소드 등을 노출시키지 않고, 단순한 이름으로 정의하는 것에 포커스.
  • 추상화의 본질
    : 클래스 정의 시, 메소드와 속성만 정의한 것을 인터페이스라고 부른다. 이것이 추상화의 본질이다.


    4. Polymorphism (다형성)
    : 똑같은 메소드라 하더라도, 다른 방식으로 구현되는 것.

  • 예 ) HTML 엘리먼트(Textarea(TextBox), Select, Checkbox) 구현 시 메소드 render로 화면에 뿌려진다고 할 때, 공통의 부모인 HTML Element라는 클래스에 render 라는 메소드가 조금씩 다르게 작동함.
    -> TextBox는 가로로 긴 네모 상자와 커서가 있는 형태, Select 박스는 눌렀을 때 선택지가 나온다. 같은 이름을 가진 메소드라도 조금씩 다르게 작동하는 것이 바로 다형성입니다.
    -> 만일 언어 자체에서 다형성을 제공하지 않는다면, 기본(부모) 클래스에 종류별로 분기를 시켜서 하나하나 다르게 만들어야 할 것이다.
    -> 또는 각각의 자식 클래스의 별도의 각기 다른 render 함수를 만들 수도 있겠지만, 엘리먼트라는 클래스의 본질상 "화면에 뿌린다"(render)는 개념은 부모가 갖고 있는 것이 합리적이다.


OOP의 주요 개념에 대한 장점

  • 캡슐화 : 코드가 복잡하지 않게 만들고, 재사용성을 높입니다.
  • 추상화 : 마찬가지로 코드가 복잡하지 않게 만들고, 단순화된 사용으로 인해 변화에 대한 영향을 최소화합니다
  • 상속 : 불필요한 코드를 줄여 재사용성을 높입니다.
  • 다형성 : 동일한 메소드에 대해 if/else if와 같은 조건문 대신 객체의 특성에 맞게 달리 작성하는 것이 가능해집니다.

결론적 OOP의 의미

: 객체 지향 프로그래밍 패러다임은 사람이 세계를 보고 이해하는 방법과 매우 흡사하다. 코드 상에서, 혹은 화면에 보이는 하나의 요소를 객체 단위로 구분시켜서 생각하면 보다 이해하기 쉬운 코드를 작성할 수 있게 됩니다. OOP의 특성을 이해하고 잘 사용하면 좋은 설계를 할 수 있습니다.

질문

  • 추상화와 캡슐화는 어떻게 다른가요?
    : 캡슐화는 은닉화(보안)에 집중. 추상화는 단순화(사용의 편리)에 집중.
  • 인터페이스(Interface)란 무엇일까요?
    : 클래스 정의 시, 메소드와 속성만 정의한 것을 인터페이스라고 부릅니다. 이것이 추상화의 본질
  • JavaScript에서 class 키워드를 사용하면, 메소드의 은닉이 가능한가요?
    : 이전의 함수 중심적인 구조적 프로그래밍 언어에서는 프로그램 내부에서 데이터가 어디서 어떻게 변경되는지 파악하기 어려웠고, 그로 인해 유지 보수가 힘들었기 때문에 자료를 중심으로 함수가 종속되는 구조가 되기도 하였다. 객체 지향에서는 클래스 내부의 데이터를 외부에서 참조하지 못하도록 차단하여 이러한 폐단을 없앨 수 있다. 이렇게 내부의 데이터나 함수를 외부에서 참조하지 못하도록 차단하는 개념을 정보 은닉(Information Hiding)이라고 하며 이것이 바로 캡슐화라는 개념이다.

클래스와 프로토타입

  • JavaScript는 프로토타입 기반 언어. 여기서 프로토타입(Prototype)은 원형 객체를 의미.
    • 상속되는 속성과 메소드들은 각 객체가 아니라 객체의 생성자의 prototype이라는 속성에 정의되어 있습니다.
class Human {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  sleep() {
    console.log(`${this.name}은 잠에 들었습니다`);
  }
}

let kimcoding = new Human('김코딩', 30);

// 실습해보세요

// 모든 생성자 함수는 constructor 속성을 지닌 객체를 프로토타입 객체로 가짐. 
// 이 constructor 속성은 원본 생성자 함수 자신을 가리키고 있다. 
Human.prototype.constructor === Human; // true

Human.prototype === kimcoding.__proto__; //  true
Human.prototype.sleep === kimcoding.sleep; //  true
  • Human이라는 클래스와 인스턴스, 그리고 프로토타입의 관계

  • Array(배열) 클래스와 인스턴스, 그리고 프로토타입의 관계
    : Array 클래스의 인스턴스로 생각할 수 있고, 프로토타입에 다양한 메소드가 존재


프로토타입 체인

Must know concepts

: 객체 지향 프로그래밍의 특성 중 "상속"을 JavaScript에서 구현할 때에는 프로토타입 체인을 사용

  • 예 ) 학생(Student)과 사람(Human)이라는 클래스가 각각 존재한다고 가정하겠습니다. 클래스 Human의 메소드와 속성을 객체로 구현한다면, 다음과 같습니다.
// < 클래스 Human의 속성과 메소드 예시 >

let kimcoding = new Human('김코딩', 30);

// 속성
kimcoding.age;
kimcoding.gender;
// 메소드
kimcoding.eat();
kimcoding.sleep();

학생은 학생이기 이전에, 사람입니다. 따라서 클래스 Student는 Human의 기본적인 메소드를 상속받을 수 있습니다. 다만, 학생은 일반적인 사람의 특징에 추가적인 특징이 필요합니다. 예를 들면 다음과 같습니다.

// < 클래스 Student의 속성과 메소드 예시 >

let parkhacker = new Student('박해커', 22);

// 속성
parkhacker.grade;
// 메소드
parkhacker.learn();

위 예시에서 나타나는 박해커(parkhacker) 씨는 Student입니다. 박해커 씨가 학생이라고 해서, age나 gender와 같은 속성이 존재하지 않거나, sleep() 이나 eat() 이라는 메소드를 사용할 수 없을까요? 그렇지 않습니다. Student는 Human의 특징을 그대로 물려받습니다.

-> 이렇게 속성과 메소드를 물려주는 클래스를 부모 클래스(여기서는 Human), 속성과 메소드를 물려받는 클래스를 자식 클래스(여기서는 Student), 그리고 이 과정을 상속이라고 합니다.

  • 자바스크립트에서 상속 구현
    • JS class 상속
    • extends : 상속 받을 클래스를 명시.
    • super : constructor()에서 첫번째로 super() 연산자를 정의하면 코드를 조금 더 읽기 쉽다. 이는 상위 클래스의 생성자를 호출, super()의 매개변수를 통해 상위 클래스의 멤버를 상속받을 수 있는 코드.
// extends 를 이용한 Person 상속
class Teacher extends Person {
  constructor(first, last, age, gender, interests, subject, grade) {
    //super를 이용한 상위 class Person의 속성값(Person의 constructor)
    super(first, last, age, gender, interests);

    // subject and grade are specific to Teacher
    this.subject = subject;
    this.grade = grade;
  }
}

Action Items

  • 브라우저에서 DOM을 이용하면, document.createElement('DIV') 으로 새로운 div 엘리먼트를 만들 수 있습니다. 이렇게 생성된 div 엘리먼트는, HTMLDivElement라는 클래스의 인스턴스입니다.

  • 모든 DOM 엘리먼트textContent와 같은 속성, 또는 append()와 같은 메소드가 있습니다. 각각의 모든 엘리먼트가 해당 메소드나 속성이 있다는 것을 통해, Element라는 공통의 부모 클래스가 있음을 짐작 가능.

  • div 엘리먼트의 클래스 모식도

    • 화살표 방향은 부모 클래스를 가리킵니다.
    • EventTarget의 부모로는, 모든 클래스의 조상인 Object가 존재합니다.
  • 개발자 도구를 사용하면, 해당 메소드나 속성이 어떤 클래스로부터 비롯되었는지 확인 가능.

    :innerText 속성은 HTMLElement로부터, textContent 속성은 Node로부터 비롯 됨.

  • 인스턴스의 __proto__를 이용하면 부모 클래스의 프로토타입, 혹은 '부모의 부모 클래스'의 프로토타입을 탐색 가능.

질문

  • addEventListener 속성은 어떤 클래스의 프로토타입에서 찾을 수 있나요?
    : EventTarget
  • remove 메소드는 어떤 클래스의 프로토타입에서 찾을 수 있나요?
    : Element
  • 모든 객체에 toString() 메소드가 존재하는 이유가 무엇인가요?
    : 모든 객체에는 객체가 텍스트 값으로 표시되거나 객체가 문자열이 예상되는 방식으로 참조 될 때 자동으로 호출되는 toString() 메서드가 있습니다. 기본적으로 toString() 메서드는 Object에서 비롯된 모든 객체에 상속됩니다. 이 메서드가 사용자 지정 개체에서 재정의되지 않으면 toString()은 [object type]을 반환합니다. 여기서 type은 object type입니다.
profile
프론트엔드 개발자

0개의 댓글