* 본 내용은 자바스크립트 DeepDive 내용을 참고하여 정리한 것입니다.
19장. 프로토타입 (11) ~ (14)
11. 직접 상속 (p.299 ~ 302)
● 11.1) Object.create에 의한 상속
- object.create메소드는 명시적으로 프로토타입을 지정하여 새로운 객체를 생성한다.
- object.create메소드도 다른 객체 생성 방식과 마찬가지로 추상 연산 OrdinaryObjectCreate를 호출함
● object Create의 메소드
- 첫 번째 매개변수: 생성할 객체의 프로토타입으로 지정할 객체를 전달
- 두 번째 매개변수: 생성할 객체의 프로퍼티 키와 프로퍼티 디스크립터 객체로 이뤄진 객체를 전달 (생략가능)
// 지정된 프로토타입 및 프로퍼티를 갖는 새로운 객체를 생성하여 반환한다.
@param {Object} prototype // 생성할 객체의 프로토타입으로 지정할 객체
@param {Object} [propertiesObject] // 생성할 객체의 프로퍼티를 갖는 객체
@returns {Object} // 지정된 프로토타입 및 프로퍼티를 갖는 새로운 객체
Object.create(prototype[,propertiesObject])
- eslint에서는 Object.prototype메소드를 통해 프로토타입 체인의 종점에 위치하는 객체를 생성할 수 있으므로, 직접 호출 방식은 권장하지 않음.
- 따라서 이 경우에는 간접 호출 방식이 필요
// 19-54 간접호출방식
const nums = Object.create(null);
nums.a = 1;
console.log(Object.prototype.hasOwnProperty.call(nums, 'a')) // true
● object Create의 메소드의 장점
- new연산자가 없어도 객체 생성 가능
- 프로토타입을 지정하면서 객체 생성 가능
- 객체 리터럴에 의해 생성된 객체도 상속 가능
- Object.prototype의 빌트인 메소드인 Object.prototype.hasownproperty, Object.prototype.isprototypeof, Object.prototype.propertyIsEnumerable 등은 모든 객체의 프로토타입의 종점(Object.prototype)의 메소드므로 모든 객체가 상속받아 호출 가능하다. (직접 호출 방식)
//19-52 Object.prototype의 빌트인 메소드를 직접 호출하기
const nums = {a:1};
console.log(nums.hasOwnProperty('a')); // true
● 11.2) 객체 리터럴 내부에서 __proto__에 의한 직접 상속
- ES6에서는 객체 리터럴 내부에서 __proto 접근자 프로퍼티를 사용하여 직접 상속 구현 가능.
// 19-55 __proto__에 의한 직접 상속
const myproto = {a:100}
const nums = {
b: 50,
__proto__: myproto // 객체를 직접 상속받는다.
};
console.log(nums.a,nums.b); // 100 50
console.log(nums.a * nums.b); // 5000
console.log(Object.getPrototypeOf(nums) === myproto); // true
12. 정적 프로퍼티/메소드 (p.303 ~ 306)
● 정적 프로퍼티/메소드의 개념
- 생성자 함수로 인스턴스를 생성하지 않아도 참조/호출할 수 있는 프로퍼티 혹은 메소드를 말함.
- 정적 프로퍼티/메소드는 인스턴스의 프로토타입 체인에 속한 객체의 프로퍼티/메소드가 아니므로, 생성자 함수가 생성한 인스턴스로 참조/호출할 수 없다.
- 하지만, object.prototype.hasOwnProperty메소드는 object.prototype(체인의 종점)의 메소드이므로 호출할 수 있다.
- 프로토타입/메소드 표기 시 prototype을 #으로 표기하는 경우도 있다.
● 예제로 확인하는 정적 프로퍼티/메소드
// 19-56 정적 프로퍼티 메소드
// 생성자 함수 만들기
function person(name) {
this.name = name;
}
// 프로토타입 메소드 만들기
person.prototype.say = function () {
console.log(`my name is ${this.name}`);
};
// 정적 프로퍼티
person.staticprop = 'static propr';
// 정적 메소드
person.staticMethod = function () {
console.log('staticMethod');
};
const me = new person('kim');
// 생성자 함수에 추가한 정적 프로퍼티/메소드는 생성자 함수로 참조 및 호출함
person.staticMethod(); // staticMethod
// 그리고, 생성자 함수가 생성한 인스턴스로는 참조 및 호출 불가함
me.staticMethod(); // TypeError: me.staticMethod is not a function
- person생성자 함수는 객체이므로, 자신의 프로퍼티/메소드를 소유할 수 있다.
- person생성자 함수 객체가 소유한 프로퍼티 / 메소드를 정적 프로퍼티/메소드라고 한다.
13. 프로퍼티 존재 확인 (p.306 ~ 307)
● in연산자
- in연산자는 객체 내 특정 프로퍼티가 존재하는지의 여부를 확인한다.
// 19-59 in연산자
const region = {
name : 'busan',
popu : 340
};
console.log('name' in region); // region객체에 name프로퍼티가 존재하므로 true
console.log('popu' in region); // region객체에 popu프로퍼티가 존재하므로 true
console.log('mayor' in region); // region객체에 mayor프로퍼티가 존재하지 않으므로 false
- in연산자는 확인 대상 객체가 상속 받은 모든 프로토타입의 프로퍼티를 확인하므로 주의한다. 즉, object.prototype의 메소드인 tostring프로퍼티를 검색한다면 true로 표시될 것이다.
- ES6에서는 in연산자 대신 Reflect.has 메소드를 사용할 수도 있다.
● Object.prototype.hasOwnProperty 메소드
- Object.prototype.hasOwnProperty메소드를 사용해서 객체에 특정 프로퍼티의 존재 여부를 확인할 수 있다.
- 객체 고유의 프로퍼티 키인 경우에만 true반환, 상속받은 프로퍼티 키일 경우 false를 반환한다.
// 19-62 hasOwnProperty
const region = {
name : 'busan',
popu : 340
};
console.log(region.hasOwnProperty('name')); // true
console.log(region.hasOwnProperty('tostring')); // false
14. 프로퍼티 열거 (p.307 ~ 312)
● 14.1) for..in문
- 기본문법은 for (변수선언문 in 객체) {...} 와 같은 형태
- in연산자처럼 순회 대상 객체 뿐만 아니라, 상속받은 프로토타입의 프로퍼티까지 열거한다.
- 다만, 객체의 모든 프로퍼티 중 프로퍼티 어트리뷰트 [[Enumerable]]의 값이 true인 경우인 프로퍼티를 순회하여 열거한다. 아래 예제를 참고해 주세요.
- 객체의 프로퍼티 개수만큼 순회하며 for~in문의 변수 선언문에서 선언한 변수에 프로퍼티 키를 할당함.
- 프로퍼티 키가 심벌인 프로퍼티는 열거하지 않는다.
// 19-65, 66
const region = {
name : 'busan',
popu : 340
};
// in연산자 사용
console.log('toString' in region); // TRUE
// for~in구문 사용
for (const key in region) {
console.log(key + ': ' + region[key]);
}
console.log(Object.getOwnPropertyDescriptor(Object.prototype, 'toString'));
/* 결과값
true
name: busan
popu: 340
{
value: [Function: toString],
writable: true,
enumerable: false,
configurable: true
}
*/
- 객체 자신의 프로퍼티만 열거하려면, 다음과 같이 Object.prototype.hasOwnProperty메소드를 사용하여 자신의 프로퍼티인지 확인해야 한다.
// 19-69
const region = {
name : 'busan',
popu : 340,
__proto__: {mayor: 'park'}
};
for (const key in region) {
if(!region.hasOwnProperty(key)) continue; // 객체 자신의 프로퍼티가 맞는지 확인
console.log(key + ': ' + region[key]);
}
- for~in문은 프로퍼티 열거 시 순서를 보장하지 않는다. 그러므로 배열의 경우, 일반적인 반복문 for문이나, for..of문(34.3절), Array.Prototype.forEach메소드(27.9절)를 사용하는 것이 좋다.
● 14.2.1) Object.keys 메소드
- for..in문에서 객체 고유 프로퍼티 열거하기 위해서는 복잡한 과정이 요구된다.
- 그러므로 객체 고유 프로퍼티만 열거하기 위해서는 Object.keys/values/entries메소드를 사용하는 것이 좋다.
- Object.keys 메소드는 객체 자신의 열거 가능한 프로퍼티 키를 배열로 반환한다.
// 19-72 Object.keys 메소드의 사용
const region = {
name : 'busan',
popu : 340,
__proto__: {mayor: 'park'}
};
console.log(Object.keys(region)); // [ 'name', 'popu' ]
● 14.2.2) Object.values 메소드
- ES8에서 도입
- Object.values메소드는 객체 자신의 열거 가능한 프로퍼티 값을 배열로 반환함
// 19-73 Object.values 메소드의 사용
const region = {
name : 'busan',
popu : 340,
__proto__: {mayor: 'park'}
};
console.log(Object.values(region)); // [ 'busan', 340 ]
● 14.2.3) Object.entries 메소드
- ES8에서 도입
- Object.entries메소드는 객체 자신의 열거 가능한 프로퍼티 키와 값의 쌍의 배열을 반환한다.
// 19-74 Object.entries 메소드의 사용
const region = {
name : 'busan',
popu : 340,
__proto__: {mayor: 'park'}
};
console.log(Object.entries(region)); // [ [ 'name', 'busan' ], [ 'popu', 340 ] ]
끝.
감사합니다.
'JavaScript' 카테고리의 다른 글
| [js] 자바스크립트 DeepDive 27장 요약 (2) : 배열 고차 함수 (0) | 2023.05.21 |
|---|---|
| [js] 자바스크립트 DeepDive 27장 요약 (1) (0) | 2023.05.20 |
| [js] 자바스크립트 DeepDive 26장 요약 (0) | 2023.05.18 |
| [js] 자바스크립트 DeepDive 19장 (6) ~ (10) 요약 (0) | 2023.03.23 |
| [js] 자바스크립트 DeepDive 19장(0) ~ (5) 요약 (0) | 2023.03.21 |
댓글