JavaScript Prototype

Garam·2023년 9월 2일
0

The Odin Project

목록 보기
8/14
post-thumbnail

Objects and Object Constructors - The prototype

Translated into Korean



개념


모든 자바스크립트 객체는 prototype이 있다. prototype은 그 자체로 독립적인 객체이며, 원형의 객체는 prototype로부터 상속을 받는다. 모든 원형의 객체는 prototype의 메소드와 속성에 접근할 수 있다. 이를 풀어서 설명하면 다음과 같다.


  1. 자바스크립트의 모든 객체는 prototype을 가진다
    예를 들어 player1player1라는 객체가 있다고 하면, 이들은 prototype을 가진다.

  2. prototypeplayer1player2라는 객체와 마찬가지로 독립적인 객체이다. prototype 객체는 다른 객체드로가 마찬가지로 속성과 메소드를 보유할 수 있다.

  3. 원형의 객체란 player1, player2와 같은 객체를 말하는 것이다. 이 객체들이 상속을 받는다는 것은 즉 이 객체들이 정의가 된 후에는 prototype의 속성과 메소드에 접근할 수 있다는 것이다.

    예를 들어 prototype.sayHello()라는 함수가 정의되어 있다면 player1도 자신의 것처럼 이 함수에 접근할 수 있다 - player1.sayHello(). .sayHello()를 호출할 수 있는 것은 player1 뿐 아니라 player1도 가능한데, 이는 함수가 prototype에 정의되어있기 때문이다.




객체의 prototype에 접근하기

Object.getPrototypeOf(player1) === Player.prototype // returns true
Object.getPrototypeOf(player2) === Player.prototype // returns true
  • 왼쪽 함수의 리턴값은 객체 생성자(Object constructor) Player(name, marker).prototype 속성이다. 이 속성의 값은 prototype 객체를 포함한다.
  • Player.prototype은 모든 Player 객체에 저장되어 있다. 따라서 player1, player2 모두 true 값을 리턴한다.



Player.prototype.sayHello = function() {
   console.log("Hello, I'm a player!");
}

player1.sayHello() // logs "Hello, I'm a player!"
player2.sayHello() // logs "Hello, I'm a player!"

Player.prototype 객체에 .sayHello 함수를 정의했으므로 모든 Player 객체에서 해당 함수를 사용할 수 있다.




Prototype를 정의하는 목적

  1. 메모리를 아낄 수 있다. prototype에 모든 common 속성과 함수를 정의하면 같은 코드를 구구절절 반복하는 과정에서 발생할 메모리 낭비를 막을 수 있다.
  2. Prototypal Inheritance를 가능하게 한다.
// Player.prototype.__proto__
Object.getPrototypeOf(player1) === Player.prototype // true
Object.getPrototypeOf(Player.prototype) === Object.prototype // true

// Output may slightly differ based on the browser
player1.valueOf() // Output: Object { name: "steve", marker: "X", sayName: sayName() }
  • Player.prototypeObject.prototype으로부터 상속받고있다.
  • .valueOf 함수는 Object.prototype에 정의되어 있는 함수이다. 이는 .sayHello와 같은 케이스다.



player1.hasOwnProperty('valueOf'); // false
Object.prototype.hasOwnProperty('valueOf'); // true
Object.prototype.hasOwnProperty('hasOwnProperty'); // true
  • 자바스크립트가 prototype을 활용하는 용도가 이것이다. prototype은 다른 prototype으로부터 상속받고, 이는 체인과 같은 구조를 형성한다. 이를 Prototypal Inheritance라고 한다. 자바스크립트는 한 속성이 어떤 객체에 존재하는지 파악하고 위치를 찾는다.



 Object.getPrototypeOf(Object.prototype); // null
  • 이는 체인의 끝을 뜻한다.
  • 만약 어떠한 속성이나 함수가 체인의 끝에서 not found 된다면, undefined가 리턴된다. (It is at the end of this chain that if the specific property or function is not found, undefined is returned)



Note:

  • 모든 prototypeObject.prototype으로부터 상속받는다.
  • 객체의 Object.getPrototypeOf() 값은 오직 하나의 독립적인 prototype만이 될 수 있다. (An object’s Object.getPrototypeOf() value can only be one unique prototype object)




setPrototypeOf

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

Person.prototype.sayName = function() {
  console.log(`Hello, I'm ${this.name}!`)
}

function Player(name, marker) {
  this.name = name
  this.marker = marker
}

Player.prototype.getMarker = function() {
  console.log(`My marker is '${this.marker}'`)
}

// Object.getPrototypeOf(Player.prototype) should
// return the value of "Person.prototype" instead
// of "Object.prototype"
Object.getPrototypeOf(Player.prototype) // returns Object.prototype

// Now make `Player` objects inherit from `Person`
Object.setPrototypeOf(Player.prototype, Person.prototype)
Object.getPrototypeOf(Player.prototype) // returns Person.prototype

const player1 = new Player('steve', 'X')
const player2 = new Player('also steve', 'O')

player1.sayName() // Hello, I'm steve!
player2.sayName() // Hello, I'm also steve!

player1.getMarker() // My marker is 'X'
player2.getMarker() // My marker is 'O'

Note:

Though it seems to be an easy way to set up Prototypal Inheritance using Object.setPrototypeOf(), the prototype chain has to be set up using this function before creating any objects. Using setPrototypeOf() after objects have already been created can result in performance issues.


0개의 댓글