Prototype이란 ?
프로토타입은 사전적 의미로 '원형'이다. 이 말을 그대로 자바스크립트에 투영해서 무엇의 원형을 나타내는지 생각하면 된다.
Javascript에서의 객체 생성
자바스크립트가 채택하고 있는 자바의 몇 가지 문법 중 대표적인 것은 new키워드이다. new키워드는 ECMAScript6 이전에 class키워드가 없었던 자바스크립트 문법에는 적합하지 않아서, 자바와 조금 다른 방식으로 채택하고있다. 자바에서는 class를 정의하지만, 자바스크립트에서는 function을 정의한다.
Function을 통한 new키워드 활용
function Person(name, blog) {
this.name = name;
this.blog = blog;
}
var shiro = new Person("shiro21", "shiro21.tistory.com");
alert(shiro.name);
위 코드를 객체지향 관점에서 봤을때, 자바스크립트에서 function은 자바의 class와 생성자를 합쳐놓은 개념이다.
객체를 생성할 때 function을 사용하는 방식은 다른 언어와 많은 차이가 있다. 따라서 ECMAScript6에서는 다른 언어와의 이질감을 줄이고, 객체지향을 조금이라도 더 지원하기 위해 class키워드를 새로 만들기도 했다.
class를 이용한 new키워드 활용
class Person {
constructor(name, blog) {
this.name = name;
this.blog = blog;
}
}
var shiro = new Person("shiro21", "shiro21.tistory.com");
alert(shiro.name);
class키워드를 이용하면 자바 등의 다른 객체지향 언어와 유사하게 클래스를 정의할 수 있다. 그런데 class키워드를 사용하면 내부적으로 특수한 function으로 정의한다는 점이다.
아래를보면 class Person의 내부 정의를 function Person정의와 다르게 하고 있는 것을 확인할 수 있다.

class키워드가 function과 다른 점은 함수처럼 바로 실행하면 에러가 발생한다는 점이다. 그리고 함수 정의와는 다르게 현재 스코프에 진입했을 때 바로 사용할 수 있는 것이 아니라, 해당 class키워드로 클래스를 선언하는 소스가 실행되고 난 이후에 객체를 생성할 수 있다.
this에 대하여
앞 코드에서 function을 이용한 new키워드를 보면 생성자 함수 안에 this를 통해 객체를 초기화하고 있는 것을 확인할 수 있다. 일반적인 객체지향 프로그래밍 언어의 관점에서 보면 당연한 표현이지만, 자바스크립트에서의 this는 조금 다르게 동작하는 경우가 많다.
함수를 호출하는 방법
- 일반 함수로의 호출
- 멤버함수로의 호출
- call()함수를 이용한 호출
- apply()함수를 이용한 호출
일반적인 함수 호출 예
function say(something) {
alert(something);
}
say("Hello World");
멤버함수 호출 예 :: 객체의 속성으로 함수를 호출 ( 함수가 객체의 멤버변수로 설정되었을때 호출하는 방법 )
var shiro = {
say: function(member) {
alert(member);
}
};
shiro.say("shiro");
call()과 apply()를 이용한 함수 호출 예 :: function객체의 기본 함수이므로 앞의 일반 함수를 호출 할 때 동일하게 호출
function say(something) {
alert(something);
}
say.call(undefined, "Hello World");
say.apply(undefined, ["Hello World !!"]);
call()과 apply()함수의 차이는 함수로 넘겨줄 인자를 따로따로 넘겨주느냐, 배열로 넘겨주느냐의 차이만 있고 나머지는 크게 다르지 않다.
함수 호출 방법에 따른 this의 변화
function whatsThis() {
return this.toString();
}
var shiro = {
what: whatsThis,
toString: function() {
return "[object shiro]";
}
};
console.log(whatsThis());
console.log(shiro.what());
console.log(whatsThis.call());
console.log(whatsThis.apply(shiro));
console.log(shiro.what.call(undefined));
console.log(shiro.what.call(shiro));
아래는 각 호출 방법에 따른 결과이다.

- 일반함수: this = window
- 멤버함수: this = shiro
- call, 인자없음: this = window
- apply, 첫번째 인자 shiro: this = shiro
- 멤버함수 call, 인자없음: this = window
- 멤버함수 call, 첫번째 인자 shiro: this = shiro
결과를 보면 1번은 일반적으로 함수가 호출될 때 내부적으로 call()함수로 변형되어서 처리되는데, 이때 call()함수의 첫번째 인자를 undefined로 넘겨주어 this의 기본값으로 window가 들어가게 된다.
따라서 call()이나 apply()함수를 이용한 함수 호출에서는 첫 번째 인자로 설정한 객체가 this로 설정되며, 인자가 넘어가지 않을 때는 일반 함수 호출과 같이 글로벌 객체인 window가 this로 설정된다.
2번은 같은 멤버함수 호출인 경우에는 내부적으로 call()함수를 호출할 때 첫번째 인자로 멤버함수를 보유한 객체를 넘겨준다. 2번 예에서는 첫번째 인자로 shiro가 넘어가기 때문에 this는 shiro가 된다.
하지만 같은 함수라도 멤버함수가 호출되는 방법이 다르면 this는 또 변경된다.
멤버함수를 다른 방법으로 호출하는 예
var newWhat = shiro.what;
console.log(newWhat()); // [object window]
이렇게 this는 함수나 스코프 기반으로 결정되는 것이 아닌 호출방법에 따라 변경된다.
'JavaScript | TypeScript > Javascript 시작하기' 카테고리의 다른 글
| [ Javascript ] 프로토타입의 사용 - 2 (0) | 2022.05.06 |
|---|---|
| [ Javascript ] 프로토타입의 사용 - 1 (0) | 2022.05.03 |
| [ Javascript ] 글로벌 변수 최소화하기 (0) | 2022.04.27 |
| [ Javascript ] JSON과 AJAX (0) | 2022.04.26 |
| [ Javascript ] 글로벌 변수 선언 방법과 차이 (0) | 2022.04.25 |

