JS Study 3주차 ( 프로토타입 3 )

jaehan·2023년 5월 1일
0

JavaScript

목록 보기
22/33
post-thumbnail

프로토타입

프로토타입 교체

프로토타입도 객체이기 떄문에 그냥 객체로 바꿀 수가 있다.

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

const me = new Person('Kim');

위 그림은 이 코드의 결과이고 Person의 프로토타입을 바꾸는 방법은

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

  Person.prototype = {
    sayHello(){
      console.log(this.name)
    }
  }
  
  return Person
})

이렇게 코드를 짜서 me에 Person객체를 할당하면 Person.prototype는 constructor는 없고 sayHello만 있는 객체로 교체된다.

그래서 아래처럼 constructor연결해주는 코드를 추가해 줘야한다.

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

  Person.prototype = {
    constructor: Person
    sayHello(){
      console.log(this.name)
    }
  }
  
  return Person
})

다른방법으로는 Object.setPrototypeOf()를 사용하는 방법이다

const parent = {
  sayHello(){
    console.log(this.name)
  }
};

Object.setPrototypeOf(me, parent);

이렇게 하면 Person.prototype이 parent객체로 바뀌는데 앞에서 생성자 함수 내부에 정의한것과는 결과가 다르다.

어떻게 다르냐면

  • 생성자 함수로 프로토타입을 교체한것은 Person의 프로토타입의 속성만 바꿧다고 생각할 수 있다.
  • Object.setPrototypeOf()은 프로토타입 자체를 다른 객체로 교체하는 것이라 Person 생성자 함수가 교체된 프로토타입인 parent객체를 모른다.

그래서 생성자 함수에서 했던것 처럼 프로토타입이랑 생성자 함수랑 연결을 해줘야 한다.

const parent = {
  constructor: Person
  sayHello(){
    console.log(this.name)
  }
};

Person.prototype = parent

Object.setPrototypeOf(me, parent);

정적 프로퍼티 / 메소드

정적 프로퍼티 메소드는 생성자 함수로 인스턴스를 생성하지 않아도 참조, 호출할 수 있는 프로퍼티 메소드 이다.

Person.staticProp = 'static prop';
Person.staticMethod = function (){
  console.log('static method')
}

Person.staticMethod();

me.staticMethod(); // TypeError

이렇게 하면 Person객체가 자기만의 값을 가지기 때문에 me에 이 정적 프로퍼티 메소드를 넘겨주지 않는다.

📌 이름을 굳이 staticMethod, staticProp 이렇게 안해도 잘된다.

프로퍼티 열거

파이썬의 for in 처럼 자바스크립트에도 for in이 있는데 좀 다르다

파이썬은 for in 하면 배열의 요소를 순회하지만 자바스크립트의 for in은 객체의 모든 프로퍼티를 순회한다.

파이썬의 for in과 같은건 for of 라고 따로 있다.

const person = {
  name: 'Kim',
  address: 'Seoul'
};

for(const key in person){
  console.log(key + ': ' + person[key]);
}

// name: Kim
// address: 'Seoul

위의 코드처럼 사용하면 된다.
person을 in으로 순회하기 때문에 key는 name, address순으로 정의된다.

여기서 문제가 있는데 for in 은 상속받은 프로토타입의 프로퍼티까지 열거한다.
대신 프로퍼티 어트리뷰트 [[Enumerable]]값이 true인 프로퍼티만 순회한다.

그래서 위의 예시에서 Object.prototype의 프로퍼티인 toString 같은 애들이 출력되지 않은것이다.
또한 프로퍼티 키가 심벌인 경우에도 열거하지 않는다.

📌 그래서 만약 사용하게 된다면 for문 안에 hasOwnProperty로 자신의 프로퍼티인지 확인하는 조건문을 걸어주는게 좋다.

❗️ 만약 배열에 for in 을 사용하면 배열도 객체이기 때문에 순회하고 배열의 인덱스가 프로퍼티이기 때문에 인덱스 값이 열거된다.

참고 :
https://www.inflearn.com/course/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C

0개의 댓글