자바스크립트에서 상속을 구현하기 위해 프로토타입을 기반으로 구현한다고 이전시간에 배워보았다.
그럼 상속을 구현하는 방법이 과연 이 방법뿐일까? 한번 알아보자.
직접상속 Object.create에 의한 직접 상속 (정적메서드) Object.create 메서드는 명시적으로 프로토타입을 지정하여 새로운 객체를 생성한다.
1 2 Object .create (생성할 객체의 프로토타입, 생성할 객체의 프로퍼티키와 프로퍼티 디스크립터 객체로 이뤄진 객체)Object .create (prototype[, propertiesObject])
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 32 33 34 35 36 37 38 39 40 41 42 43 44 let obj = Object .create (null );console .log (Object .getPrototypeOf (obj) === null ); console .log (obj.toString ()); obj = Object .create (Object .prototype , { x : { value : 1 , writable : true , enumerable : true , configurable : true }, }); console .log (obj.x ); console .log (Object .getPrototypeOf (obj) === Object .prototype ); const obj1 = Object .create (obj, { x : { value : 10 }, y : { value : 20 , writable : true }, }); console .log (obj1); const myProto = { x : 10 };obj = Object .create (myProto); console .log (obj.x ); console .log (Object .getPrototypeOf (obj) === myProto); console .log (Object .getPrototypeOf (obj) === Object .prototype ); function Person (name ) { this .name = name; } obj = Object .create (Person .prototype ); obj.name = "Lee" ; console .log (obj.name ); console .log (Object .getPrototypeOf (obj) === Person .prototype );
Object.create 메서드의 첫번째 인수로 전달한 객체를 프로토타입으로 하는 프로토타입 체인에 속하는 객체를 생성한다. 즉, 객체를 생성하면서 직접적인 상속을 구현하는 것이다.
new 연산자 없이 객체 생성 가능
프로토타입을 지정하면서 객체 생성 가능
객체 리터럴로 생성된 객체도 상속받을 수 있다.
Object.prototype의 빌트인 메서드를 직접 호출하는 것은 위험하다. 그 이유는 Object.create 메서드를 사용하여 프로토타입 체인 종점에 위치하는 객체 를 생성할 수도 있기 때문이다.
1 2 3 4 5 6 7 8 const obj = Object .create (null );obj.a = 1 ; console .log (Object .getPrototypeOf (obj) === null ); console .log (obj.hasOwnProperty ("a" ));
그러므로 Object.prototype의 빌트인 메서드는 call,apply 등을 통해 간접적으로 호출하는 것을 권장한다.
하지만 위 방법은 너무 길다…
그래서 새로나온 문법을 사용하자
1 Object .hasOwn (obj, property);
위 방법을 사용하여 같은 기능을 구현할 수 있다.
정적 프로퍼티/메소드 생성자 함수로 인스턴스를 생성하지 않아도 참조,호출할 수 있는 프로퍼티, 메소드를 말한다.
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 function Person (name ) { this .name = name; } Person .prototype .sayHello = function ( ) { console .log (`Hi! My name is ${this .name} ` ); }; Person .staticProp = "static prop" ;Person .staticMethod = function ( ) { console .log ("staticMethod" ); }; const me = new Person ("Lee" );Person .staticMethod (); me.staticMethod ();
생성자 함수로 생성한 인스턴스로 정적 프로퍼티와 메소드를 참조, 호출할 수 없다.
생성자 함수가 생성한 인스턴스는 프로퍼티, 메소드를 참조할 때 프로토타입 체인 내에서만 할 수 있다.
정적 프로퍼티,메소드는 인스턴스의 프로토타입 체인 내에 없기 때문에 참조, 호출할 수 없다.
💡 MDN에 보면 정적메서드와 프로토타입 메서드를 구분하여 소개한다. 정적 메서드는 Object.isExtensible(), Object.keys() 처럼 중간에 prototype이 들어가지 않지만 프로토타입 메서드는 Object.prototype.hasOwnProperty() 처럼 중간에 prototype이 들어간다.