[JS interview] Prototype 및 call/apply/bind 차이 등
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?