티스토리 뷰

mdn 같은 곳의 문서를 보면 어떤 메서드를 설명할 때 Object.prototype.~~~라고 표시된 메서드와

단순히 Object.~~~ 라고 표시된 메서드가 있다.

 

이것을 이해하면 해당 메서드를 인스턴스를 통해 호출해서 사용해야 하는지,

아니면 인스턴스를 만들지 않고 생성자함수 그대로 사용할 수 있는지 결정할 수 있으며

해당 메서드의 탄생 의도를 파악하는데도 도움이 된다.

그리고 무엇보다 문서를 제대로 읽으려면 알아야 한다.

 

결론부터 말하자면 Object.prototype.toString()는 프로토타입 메서드이고 Object.keys()는 정적메서드이다.

 

프로토타입 메서드 vs 정적 메서드

두 차이를 이해하려면 프로토타입에 대해서 이해해야 한다. 

프로토타입은 자바스크립트가 객체를 생성할 때 메모리를 효율적으로 사용하고 불필요한 중복을 제거하려는 목적으로 프로토타입을 이용해서 상속을 구현한다. 자바스크팁트의 모든 객체는 프로토타입을 가진다. 생성방식에 따라 차이가 있지만 리터럴 방식이든, 생성자 함수를 사용하든, 클래스를 사용하든 언제나 객체는 프로토타입을 가진다. 예를 들어 리터럴 방식으로 생성된 객체는 Object.prototype을 프로토타입으로 가진다.

생성자함수로 생성된 인스턴스객체도 프로토타입을 가지는데 그 상위로 프로토타입체인을 타고 올라가 보면

contructor프로퍼티와 prototype 프로토타입을 가지고 이것이 Object.prototype이다. 

아무튼 말하고자 하는 내용은 객체는 프로토타입을 가지고 이것을 상속받으면서 프로토타입 체인을 형성한다.

자세한 내용은 딥다이브를 공부해 주시면 된다.

즉 프로토타입 체인이란 상위객체의 프로토타입을 상속받음으로써 상위객체의 프로퍼티나 메서드를 호출할 수 있게 해주는 메커니즘이다.

딥다이브 자바스크립트 304p

위 이미지가 정적메서드와 프로토타입 메서드의 차이를 설명하기에 딱 좋은 이미지라고 생각한다.

한마디로 프로토타입 메서드란 프로토타입 체인에 속해서 모든 인스턴스가 상속받아 사용할 수 있는 메서드라고 할 수 있다. 이미지에서 빨간 점선으로 표시된 me객체의 프로토타입 체인에 해당되는 부분이다. 이미지에서는 상위 프로토타입에 존재하는 sayHello라는 메서드가 바로 프로토타입 메서드이다. 그리고 그 상위 프로토타입에는 hasOwnProperty라는 메서드도 역시 프로토타입 메서드이므로 인스턴스가 사용할 수 있다. 

간단하게 생성자함수의 프로토타입에 sayJS라는 프로토타입메서드를 추가했다. me객체는 이것을 상속받아 사용할 수 있다.

마찬가지로 생성자 함수가 상속받은 프로토타입 즉, Object.prototype에 존재하는 hasOwnProperty도 마치 객체의 메서드처럼 호출해서 사용할 수 있다. 이것이 프로토타입 메서드이고, Object.prototype.toString() 이런 식으로 표기되어 있다.

 

반면에 정적메서드란 프로토타입 체인 바깥쪽의 생성자함수가 직접 가지고 있는 메서드이다. 프로토타입체인을 타고 있지 않기 때문에 이 메서드를 사용하려면 생성자함수를 직접 호출해야 한다.

정적메서드는 위와 같이 생성자함수의 프로퍼티로 직접 추가되며, 프로토타입체인에 속하지 않기 때문에 인스턴스는 호출할 수 없다.

이를 호출하려면 직접 생성자함수를 호출해야 한다. 이런 정적메서드들은 Object.keys()처럼 표시된다.

 

빌트인 객체 중 생성자 함수로서 호출할 수 있는 객체는 당연하게도(인스턴스를 만들 목적의 함수이므로) 프로토타입 메서드와 정적메서드 둘 다 제공한다. 반면 생성자 함수로 호출할 수 없는 빌트인 객체, 예를 들면 Math, JSON, Reflect는 정적메서드만 제공한다. 당연하다. 생성자 함수가 아니니 인스턴스를 만들 수 없고 인스턴스가 호출하는 프로토타입 메서드도 당연히 있을 수 없는 것이다.

그래서 Math.random(), Math.ceil() 이런 식으로 항상 생성자 함수에서 직접 호출할 수밖에 없는 것이다.

 

String 생성자 함수는 뭘까? 

우리는 보통 문자열 원시값을 리터럴로 생성한다. 예를 들면

const str = "hello world";

 

그럼에도 불구하고 우리는 이런 걸 할 수 있다.

const str = "hello world";
str.toUpperCase() // "HELLO WORLD"

마치 원시값인 문자열이 객체인 것처럼 메서드를 호출한다.

맞다. toUpperCase()는 프로토타입 메서드였다.

원시값인 문자열에 메서드 호출하듯이 .toUpperCase()를 작성하면 자바스크립트 엔진은 암묵적으로 문자열객체를 생성한다

위와 같이 String 생성자 함수를 호출해서 객체로 감싼 문자열을 만들어서 프로토타입메서드를 호출할 수 있게 도와준다.

이것을 래퍼객체라고 한다. 그리고 위 과정이 끝나면 바로 원시값으로 돌려준다.

우리가 'hello world'.toUpperCase()를 사용할 수 있었던 건 마법이 아니라 자바스크립트 엔진이 열일하기 때문이었다.

이제 문서를 볼 때 prototype. 이 붙어있는 메서드들을 볼 때마다 이해하며 볼 수 있다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함