프론트엔드 기술/VanillaJS

[JS interview] Prototype 및 call/apply/bind 차이 등

pogles 2023. 1. 15. 17:53

Prototype 이란?

 

자바스크립트는 프로토타입 기반 객체지향언어이다. c++ 이나 java 는 클래스기반 객체지향언어이라는 점에서 다르다.

자바스크립트에서는 존재하고 있는 객체를 프로토타입으로 사용하고, 프로토타입 객체를 복사하여 재사용하는 것을 상속이라고 부른다. 즉, 클래스기반 OOP 에서의 상속의 개념과 비슷하다

 

클래스기반 batter player 와 pitcher player 의 부모가 baseball player
프로토타입기반 batter player 와 pitcher player 의 프로토타입이 baseball player 

 

자바스크립트에서는 사용자가 특정한 객체를 생성하면, 그 객체에 대한 프로토타입도 자동적으로 가지게 된다.

객체들은 프로토타입 객체를 통해 메서드나 변수들을 상속받는다. 

 

 

 

프로토타입을 만들기 위해서 객체 생성자 함수를 사용한다. 즉, 함수를 이용해서 객체를 만들면 되는 것이다.

 

** new 연산자를 사용해 객체를 생성하면, 같은 프로토타입을 가지는 객체들을 생성할 수 있다.

** 또한 자바스크립트의 객체들은 프로토타입로 Object.prototype 객체를 가진다.

function Marine() = { // 객체 생성자 함수 >> 프로토타입 생성
    hp=40;
    attack=6;
    armor=0;
}

var unit1 = new Marine();
var unit2 = new Marine();
// unit1 이라는 객체의 프로토타입은 Marine (Marine.prototype) 이다.
// unit2 이라는 객체또한 프로토타입은 Marine (Marine.protoype) 이다.
// 또한 모든 객체들의 프로토타입에 Object.prototype 이 포함된다.

 

Prototype chain 이란?

 

이렇게 객체와 그 객체의 프로토타입 사이에 상호작용이 가능한, 연결된 가상의 연결고리를 프로토타입 체인이라고 한다.

 

  • 객체 인스턴스 프로토타입 반환 : Object.getPrototypeOf(Object)  /  __proto__ 속성을 통해 사용(권장되지 않음)
var proto = {};
var obj = Object.create(proto);
Object.getPrototypeOf(obj) === proto; // true

 

 


 

함수에서의 call, apply, bind

 

 

1) call 

함수명.call( obj, argument1, argument2, ... )

 

** call 은 객체정보인수를 받아서 함수를 호출한다.

*** this 는 call 에서 받는 객체를 가르킨다.

 

var employee1 = { firstName: "John", lastName: "Rodson" };
var employee2 = { firstName: "Jimmy", lastName: "Baily" };

function invite(greeting1, greeting2) {
  console.log(
    greeting1 + " " + this.firstName + " " + this.lastName + ", " + greeting2
  );
}

invite.call(employee1, "Hello", "How are you?"); // Hello John Rodson, How are you?
invite.call(employee2, "Hello", "How are you?"); // Hello Jimmy Baily, How are you?

 

 

2) apply

함수명.apply( obj , [argu1, argu2, argu3, ... ]

 

* call 은 인수를 그대로 받고, apply 는 인수가 들어있는 배열을 받는다.

** apply 는 객체정보와 인수가 담겨있는 배열을 받아서 호출한다.

*** this 는 apply 에서 받는 객체를 가르킨다.

 

var employee1 = { firstName: "John", lastName: "Rodson" };
var employee2 = { firstName: "Jimmy", lastName: "Baily" };

function invite(greeting1, greeting2) {
  console.log(
    greeting1 + " " + this.firstName + " " + this.lastName + ", " + greeting2
  );
}

invite.apply(employee1, ["Hello", "How are you?"]); // Hello John Rodson, How are you?
invite.apply(employee2, ["Hello", "How are you?"]); // Hello Jimmy Baily, How are you?

 

 

3) bind

 

(제가 이해한 바를 정리했기에 정확하지 않을 수 있습니다)

bind 는 바로 함수에 접근하는 것이 아니라 일단 호출할 함수에 객체를 바운드 시켜 새로운 함수를 만들고, 그 새로운 함수에서 인수를 받아서 함수를 호출하는 방법입니다.

 

** 먼저 객체를 넘겨준 이후 따로 인수를 전달하고 싶을 때 사용합니다.

 

1.  let 새로운 함수명 == 함수명.bind(객체)    >>     일단 함수에 객체를 바운드 시킨 새로운 함수를 만든다..

2. 새로운 함수명(인수1, 인수2, ... )    >>    새로운 함수에 나머지 인수를 받는다.

 

var employee1 = { firstName: "John", lastName: "Rodson" };
var employee2 = { firstName: "Jimmy", lastName: "Baily" };

function invite(greeting1, greeting2) {
  console.log(
    greeting1 + " " + this.firstName + " " + this.lastName + ", " + greeting2
  );
}

var inviteEmployee1 = invite.bind(employee1);
var inviteEmployee2 = invite.bind(employee2);
inviteEmployee1("Hello", "How are you?"); // Hello John Rodson, How are you?
inviteEmployee2("Hello", "How are you?"); // Hello Jimmy Baily, How are you?