프로토타입 상속
다른 데이터 유형과 마찬가지로 객체는 내장된 Object
프로토타입에서 속성과 메서드를 상속합니다. 즉, 결과 객체에는 정의한 속성과 프로토타입에서 상속된 메서드를 포함하는 프로토타입 속성이 모두 포함됩니다.
let myObject = {
'booleanValue' : true
};
myObject;
> Object { booleanValue: true }
booleanValue: true
[[prototype]]: Object { … }
__defineGetter__: function __defineGetter__()
__defineSetter__: function __defineSetter__()
__lookupGetter__: function __lookupGetter__()
__lookupSetter__: function __lookupSetter__()
__proto__: …
constructor: function Object()
hasOwnProperty: function hasOwnProperty()
isPrototypeOf: function isPrototypeOf()
propertyIsEnumerable: function propertyIsEnumerable()
toLocaleString: function toLocaleString()
toString: function toString()
valueOf: function valueOf()
<get __proto__()>: function __proto__()
<set __proto__()>: function __proto__()
프로토타입 속성은 속성 키로 직접 액세스할 수 없습니다. 이전 예에서 볼 수 있듯이 이는 브라우저의 개발자 콘솔과 프로토타입의 속성 키 문서 소스에서 사용된 [[prototype]]
또는 <prototype>
표기법을 통해 암시됩니다.
// Chrome:
let emptyObject = {};
emptyObject;
> {}
[[prototype]]: Object
// Firefox:
let emptyObject = {};
emptyObject;
> Object { }
<prototype>: Object { … }
모든 일반 브라우저에서 사실상의 표준으로 __proto__
를 사용하지만 공식적으로 표준화되지 않았으므로 프로덕션 코드에서는 이를 피해야 합니다.
let emptyObject = {};
emptyObject.__proto__;
> Object { … }
__defineGetter__: function __defineGetter__()
__defineSetter__: function __defineSetter__()
__lookupGetter__: function __lookupGetter__()
__lookupSetter__: function __lookupSetter__()
__proto__:
constructor: function Object()
hasOwnProperty: function hasOwnProperty()
isPrototypeOf: function isPrototypeOf()
propertyIsEnumerable: function propertyIsEnumerable()
toLocaleString: function toLocaleString()
toString: function toString()
valueOf: function valueOf()
<get __proto__()>: function __proto__()
<set __proto__()>: function __proto__()
대신 내장된 Object.getPrototypeOf()
및 Object.setPrototypeOf()
메서드를 사용하여 객체의 [[Prototype]]
에 직접 액세스하고 수정할 수 있습니다.
let myObj = { "value" : 5 };
let protoParent = { "protoValue" : true };
myObj;
Object { value: 5 }
value: 5
<prototype>: Object { … }
Object.getPrototypeOf( myObj );
> Object { … }
__defineGetter__: function __defineGetter__()
__defineSetter__: function __defineSetter__()
__lookupGetter__: function __lookupGetter__()
__lookupSetter__: function __lookupSetter__()
__proto__:
constructor: function Object()
hasOwnProperty: function hasOwnProperty()
isPrototypeOf: function isPrototypeOf()
propertyIsEnumerable: function propertyIsEnumerable()
toLocaleString: function toLocaleString()
toString: function toString()
valueOf: function valueOf()
<get __proto__()>: function __proto__()
<set __proto__()>: function __proto__()
Object.setPrototypeOf( myObj, protoParent );
> Object { value: 5 }
value: 5
<prototype>: Object { protoValue: true }
상속된 속성과 작성자가 정의한 속성을 구분하기 위해 후자를 일반적으로 객체의 '자체 속성'이라고 합니다.
기본 제공되는 Object.hasOwn()
메서드는 지정된 속성이 객체의 직접 속성인 경우 true
를 반환하고 속성이 상속되거나 존재하지 않으면 false
를 반환합니다. 가능하면 Object.create()
를 지원하지 않는 상속된 hasOwnProperty()
메서드 대신 Object.hasOwn()
를 사용하세요.
let myObject = {
'myValue' : 100
};
Object.hasOwn( myObject, 'myValue' );
> true
myObject.__proto__; // The Object prototype inherited by `myObject` is present:
> Object { … }
Object.hasOwn( myObject, '__proto__' ); // The Object prototype inherited by `myObject` is not an "own property:"
> false
이해도 테스트
__proto__
를 사용하면 안 되는 이유는 무엇인가요?