일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 연습문제
- Kotlin
- map
- 백준 java
- 카카오
- java 백준 1차원 배열
- 문자열
- 스프링 빈
- Java
- 반복문
- 코테
- 개발자 회고록
- 월간코드챌린지
- 리눅스마스터1급
- 고잉버스
- 리눅스마스터 3과목
- toCharArray
- 리눅스
- Memoir
- 명령어
- GoingBus
- 스프링 컨테이너
- 자바
- 자바스크립트 코딩의 기술
- Linux
- 코딩테스트
- 리눅스마스터 1급 정리
- JavaScript
- 백준 javascript
- 프로그래머스
- Today
- Total
hoon's bLog
Javascript 객체 Object 상속, 프로토타입 prototype, 순회 본문
객체의 전반적인 기본 개념을 보시려면 "객체(1)" ← ← 포스팅을 참고해 주세요!!
상속(inheritance)
- 새로운 클래스에서 기존 클래스의 모든 프로퍼티와 메서드를 사용할 수 있는 것
- 상속을 통해 새로운 프로그램의 요구에 맞게 기존 클래스를 수정하여 재사용 가능
- 클래스 간의 종속 관계를 형성함으로써 객체의 관계를 조직화 가능
자바스크립트는 프로토타입 기반(prototype-based)의 객체 지향 언어
자바스크립트에서는 현재 존재하고 있는 객체를 프로토타입으로 사용하여, 해당 객체를 복제하여 재사용하는 것을 상속이라고 함.
프로토타입(prototype)
- 자바스크립트의 모든 객체는 프로토타입(prototype)이라는 객체를 가지고 있음
- 모든 객체는 그들의 프로토타입으로부터 프로퍼티와 메서드를 상속
- 이처럼 자바스크립트의 모든 객체는 최소한 하나 이상의 다른 객체로부터 상속을 받으며, 이때 상속되는 정보를 제공하는 객체를 프로토타입(prototype)
- 자바스크립트에서는 객체 이니셜라이저를 사용해 생성된 같은 타입의 객체들은 모두 같은 프로토타입
- 또한, new 연산자를 사용해 생성한 객체는 생성자의 프로토타입을 자신의 프로토타입으로 상속
let obj = new Object(); // 이 객체의 프로토타입은 Object.prototype
let arr = new Array(); // 이 객체의 프로토타입은 Array.prototype
let date = new Date(); // 이 객체의 프로토타입은 Date.prototype
- 하지만 Object.prototype 객체는 어떠한 프로토타입도 가지지 않으며, 아무런 프로퍼티도 상속받지 않음
- 또한, 자바스크립트에 내장된 모든 생성자나 사용자 정의 생성자는 바로 이 객체를 프로토타입으로 가짐
프로토타입 체인(prototype chain)
- 프로토타입이 상속되는 가상의 연결 고리
- Object.prototype 객체는 이러한 프로토타입 체인에서도 가장 상위에 존재하는 프로토타입
- 자바스크립트의 모든 객체는 Object.prototype 객체를 프로토타입으로 상속
let date = new Date(); // 이 객체는 Date.prototype 뿐만 아니라 Object.prototype도 프로토타입으로 가짐.
프로토타입의 생성
- 객체 생성자 함수(object constructor function)를 작성
- 생성자 함수를 작성하고 new 연산자를 사용해 객체를 생성하면, 같은 프로토타입을 가지는 객체들을 생성 가능
function Dog(color, name, age) { // 개에 관한 생성자 함수를 작성함.
this.color = color; // 색에 관한 프로퍼티
this.name = name; // 이름에 관한 프로퍼티
this.age = age; // 나이에 관한 프로퍼티
}
let myDog = new Dog("누런색", "누렁이", 1); // 이 객체는 Dog라는 프로토타입을 가짐.
document.write("우리 집 강아지는 " + myDog.name + "라는 이름의 " + myDog.color + "을 가진 강아지");
- 객체 생성자 함수를 작성할 때에는 관례상 이름의 첫 문자만을 대문자로 작성
- 객체에 프로퍼티 및 메서드 추가
function Dog(color, name, age) {
this.color = color;
this.name = name;
this.age = age;
}
let myDog = new Dog("누런색", "누렁이", 12);
myDog.family = "시고르자브종"; // 품종에 관한 프로퍼티를 추가함.
myDog.breed = function() { // 털색을 포함한 품종을 반환해 주는 메서드를 추가함.
return this.color + " " + this.family;
}
document.write("우리 집 강아지는 " + myDog.breed() + "");
- 위의 에서 새롭게 추가된 weight 프로퍼티와 breed() 메서드는 오직 myDog 인스턴스에만 추가
- 이미 생성된 다른 Dog 객체나 차후에 생성되는 어떠한 다른 Dog 객체에도 추가되지 않음
프로토타입에 프로퍼티 및 메서드 추가
프로토타입의 경우에는 생성자 함수에 직접 추가해야만 이후에 생성되는 모든 다른 객체에도 적용 가능
function Dog(color, name, age) {
this.color = color;
this.name = name;
this.age = age;
this.family = "시고르자브종"; // 프로토타입에 프로퍼티를 추가할 때에는 기본값을 가지게 할 수 있음.
this.breed = function() {
return this.color + " " + this.family;
};
}
let myDog = new Dog("흰색", "흰둥이", 1);
let hisDog = new Dog("갈색", "갈뱅이", 3);
document.write("우리 집 강아지는 " + myDog.family + "이고, 친구네 집 강아지도 " + hisDog.family + "");
Prototype 프로퍼티
Prototype 프로퍼티를 이용하면 현재 존재하고 있는 프로토타입에 새로운 프로퍼티나 메서드를 손쉽게 추가 가능
function Dog(color, name, age) {
this.color = color;
this.name = name;
this.age = age;
}
// 현재 존재하고 있는 Dog 프로토타입에 family 프로퍼티를 추가함.
Dog.prototype.family = "시고르자브종";
// 현재 존재하고 있는 Dog 프로토타입에 breed 메서드를 추가함.
Dog.prototype.breed = function() {
return this.color + " " + this.family;
};
let myDog = new Dog("흰색", "흰둥이", 1);
let hisDog = new Dog("갈색", "갈뱅이", 3);
document.write("우리 집 강아지는 " + myDog.family + "이고, 친구네 집 강아지도 " + hisDog.family + "");
document.write("우리 집 강아지의 품종은 " + myDog.breed() + "<br>");
document.write("친구네 집 강아지의 품종은 " + hisDog.breed() + "");
- 직접 생성한 프로토타입은 위와 같이 새로운 프로퍼티나 메서드를 마음껏 추가하거나 삭제 가능
- 물론 자바스크립트 표준 객체의 프로토타입도 임의로 수정할 수 있으나, 심각한 오류가 발생할 가능성이 있음
- 따라서 자바스크립트 표준 객체의 프로토타입은 수정 X
객체 다루기
this 키워드
- 해당 키워드가 사용된 자바스크립트 코드 영역을 포함하고 있는 객체
- 메서드 내부에서 사용된 this 키워드는 해당 메서드를 포함하고 있는 객체!
- 또한, 객체 내부에서 사용된 this 키워드는 객체 그 자신!
- 이러한 this는 변수가 아닌 키워드이므로, 사용자가 임의로 가리키는 값 변경 불가!!
- 객체 생성자 함수 내부에서 사용된 this 키워드는 어떠한 값도 가지지 않으며, 단순히 새로운 객체로 대체
delete 키워드
- 객체의 프로퍼티를 삭제 가능
- delete 키워드를 사용하여 프로퍼티를 삭제하면, 프로퍼티의 값뿐만 아니라 프로퍼티 그 자체도 삭제
- 본래 객체의 프로퍼티만을 삭제하기 위해 만들어졌기 때문에 함수나 변수에 적용 불가
delete 객체이름.프로퍼티이름;
function Dog(color, name, age) {
this.color = color;
this.name = name;
this.age = age;
}
let myDog = new Dog("흰색", "마루", 1);
delete myDog.age; // age 프로퍼티를 삭제함.
// age 프로퍼티가 삭제되었기 때문에 undefined를 출력함.
document.write("우리집 강아지의 나이는 " + myDog.age + "입니다.");
- 직접 생성한 프로토타입은 위와 같이 새로운 프로퍼티나 메서드를 마음껏 추가하거나 삭제 가능
- 자바스크립트 표준 객체의 프로토타입도 임의로 수정할 수 있으나, 심각한 오류가 발생을 일으킴.
객체 프로퍼티의 순회
- 자바스크립트에서는 for / in 문을 사용하여 객체의 모든 프로퍼티를 반복 가능
- for / in 문은 객체의 모든 열거할 수 있는 프로퍼티(enumerable properties)를 손쉽게 순회
- 객체의 프로퍼티를 순회하는 방법으로는 for / in 문 이외에도 다음과 같은 메서드를 사용 가능
Object.keys()
메서드는 해당 객체가 가진 고유 프로퍼티 중에서 열거할 수 있는 프로퍼티의 이름을 배열에 담아 반환
Object.getOwnPropertyNames()
메서드는 해당 객체가 가진 모든 고유 프로퍼티의 이름을 배열에 담아 반환
function Dog(color, name, age) {
this.color = color;
this.name = name;
this.age = age;
}
let myDog = new Dog("흰색", "마루", 1);
// color 프로퍼티의 enumerable 속성을 false로 설정함.
Object.defineProperty(myDog, 'color', {enumerable : false} );
// 객체가 가진 고유 프로퍼티 중에서 열거할 수 있는 프로퍼티 이름을 배열에 담아 반환
document.write(Object.keys(myDog) + "<br>"); // name, age
// 객체가 가진 모든 고유 프로퍼티의 이름을 배열에 담아 반환
document.write(Object.getOwnPropertyNames(myDog)); // color, name, age
Object.defineProperty() //메서드는 ECMAScript 5부터 추가된 객체에 프로퍼티를 추가해 주는 메서드
// 이때 추가하는 프로퍼티의 속성까지도 설정 할 수 있다.
객체 간의 비교 : 자바스크립트에서 별개의 두 객체는 프로퍼티의 값이 모두 같아도, 절대로 같다고 말할 수 없습니다.
function Dog(color, name, age) {
this.color = color;
this.name = name;
this.age = age;
}
let myDog = new Dog("흰색", "마루", 1);
let hisDog = new Dog("흰색", "마루", 1); // 모든 프로퍼티의 값이 모두 같은 객체를 생성함.
document.write((myDog == hisDog) + "<br>"); // false
document.write((myDog === hisDog) + "<br>"); // false
let herDog = hisDog; // hisDog 객체를 변수 herDog에 대입함.
document.write((hisDog == herDog) + "<br>"); // true
document.write((hisDog === herDog) + "<br>"); // true
- 위의 코드에서 myDog과 hisDog 객체는 가지고 있는 프로퍼티의 값이 모두 동일
- 하지만 이 두 객체는 별개의 객체이므로, 동등(==) 연산자와 일치(===) 연산자로 비교해도 모두 false를 반환
- 위의 에서는 변수 herDog에 hisDog 객체를 대입
- 이렇게 객체를 대입한 변수를 객체 레퍼런스(object reference)라고 하며, 이제부터 변수 herDog은 hisDog 객체를 가리킴
- 객체 레퍼런스는 객체 자체를 저장하는 것이 아니라, 객체가 위치한 주소를 저장하기 때문에, 변수 herDog과 hisDog을 동등 연산자와 일치 연산자로 비교하면, 모두 true를 반환
객체 프로퍼티(property)
- 모든 자바스크립트 객체는 Object 객체와 Object.prototype 객체의 모든 프로퍼티를 상속
- prototype 프로퍼티를 이용하면 현재 존재하는 프로토타입에 새로운 프로퍼티나 메서드를 손쉽게 추가
객체 메서드(method)
모든 자바스크립트 객체는 Object 객체와 Object.prototype 객체의 모든 프로퍼티와 메서드를 상속
hasOwnProperty()
- 특정 프로퍼티가 해당 객체에 존재하는지를 검사
- 해당 객체에서 직접 선언된 프로퍼티만을 검사하며, 같은 이름의 프로퍼티라도 상속받은 프로퍼티는 false 값을 반환
function Dog(color, name, age, family) {
this.color = color;
this.name = name;
this.age = age;
this.family = family;
this.breed = function() {
return this.color + " " + this.family;
}
}
let myDog = new Dog("검정색", "곰", 3, "불독");
myDog.hasOwnProperty("color"); // true
myDog.hasOwnProperty("breed"); // true
myDog.hasOwnProperty("class"); // 상속받은 프로퍼티이므로, false를 반환
propertyIsEnumerable()
- 특정 프로퍼티가 해당 객체에 존재하고, 열거할 수 있는 프로퍼티인지를 검사
- hasOwnProperty() 메서드의 결과가 true이면서, 동시에 열거할 수 있는 프로퍼티인지를 검사
function Dog(color, name, age) {
this.color = color;
this.name = name;
this.age = age;
}
let myDog = new Dog("흰색", "마루", 1);
// color 프로퍼티의 enumerable 속성을 false로 설정함.
Object.defineProperty(myDog, 'color', { enumerable : false} );
document.write(myDog.propertyIsEnumerable("color") + "<br>"); // false
document.write(myDog.propertyIsEnumerable("name") + "<br>"); // true
document.write(myDog.propertyIsEnumerable("age")); // true
열거할 수 있는 프로퍼티
- 내부적으로 enumerable 플래그가 true로 설정된 프로퍼티
- 이러한 프로퍼티들은 for / in 문으로 접근 가능
- 이때 추가하는 프로퍼티의 속성까지도 설정 할 수 있음.
isPrototypeOf()
특정 객체의 프로토타입 체인에 현재 객체가 존재하는지를 검사
let day = new Date(); // Date 객체를 생성함.
// 객체 day의 프로토타입이 Date.prototype인지를 검사함.
document.write(Date.prototype.isPrototypeOf(day)); // true
document.write(Date.prototype.isPrototypeOf(new String())); // false
isExtensible()
- 객체에 새로운 프로퍼티를 추가할 수 있는지 여부를 반환
- 자바스크립트에서 모든 객체는 기본적으로 새로운 프로퍼티를 추가 가능
- 하지만 preventExtensions() 메서드를 사용하여 해당 객체에 새로운 프로퍼티를 추가할 수 없도록 설정 할 수 있음.
let day = new Date(); // Date 객체를 생성함.
// 객체 day에 새로운 프로퍼티를 추가할 수 있는지 검사함.
document.write(Object.isExtensible(day) + "<br>"); // true
// 해당 객체에 새로운 프로퍼티를 추가할 수 없도록 설정함.
let myDay = Object.preventExtensions(day);
document.write(Object.isExtensible(day)); // false
toString()
이 메서드를 호출한 객체의 값을 문자열로 반환
let arr = [10, "문자열", true]; // 배열
let bool = false; // 불리언
function func() { return 0; } // 함수
arr.toString(); // 10, 문자열, true
bool.toString(); // false
func.toString(); // 함수의 소스 코드가 전부 문자열로 반환됨.
valueOf()
- 특정 객체의 원시 타입(primitive type)의 값을 반환
- 자바스크립트에서는 원시 타입의 값이 기대되는 곳에 객체가 사용되면, 내부적으로 이 메서드를 호출하여 처리
- 만약 어떤 객체가 원시 타입의 값을 가지고 있지 않다면, 객체 자신을 반환
function func(n) {
this.number = n;
}
myFunc = new func(4);
document.write(myFunc + 5); // ① : [object Object]5
func.prototype.valueOf = function() { // valueOf() 메서드를 정의함.
return this.number;
}
document.write(myFunc + 5); // ② : 9
- 위의 ① 부분에서는 산술 연산을 위해 number 타입의 값을 기대하는 곳에 myFunc 객체가 사용
- 자바스크립트는 내부적으로 해당 객체의 valueOf() 메서드를 호출
- 하지만 이 객체의 valueOf() 메서드는 아직 정의되지 않았으므로, 해당 객체 자신을 반환
- 산술 연산이 아닌 문자열 결합 연산이 수행
- 그 후에 prototype 프로퍼티를 이용하여 valueOf() 메서드를 정의
- 따라서 ② 부분에서는 내부적으로 호출된 valueOf() 메서드가 해당 객체의 number 프로퍼티 값을 반환하고, 정상적으로 산술 연산 수행
getter와 setter
접근자 프로퍼티라고 부릅니다.
getter : 특정 프로퍼티의 값을 받아오기 위한 메서드
setter : 특정 프로퍼티의 값을 설정하기 위한 메서드
let gildong = { age: 18 };
document.write(gildong.age + "<br>"); // 18
Object.defineProperty(gildong, "americanAge", { get: function() { return this.age - 1; } });
document.write(gildong.americanAge); // 17
- 위의 에서는 gildong 객체에 americanAge라는 프로퍼티를 추가할 때 get 키워드를 사용하여 getter 메서드를 정의
- 따라서 해당 프로퍼티를 참조하려고 할 때는 내부적으로 미리 정의한 getter 메서드가 자동으로 호출될 것
let gildong = { age: 18 };
gildong.age = 20;
document.write(gildong.age + "<br>"); // 20
Object.defineProperty(gildong, "changeAge", { set: function(n) { this.age = this.age - n; } });
gildong.changeAge = 5;
document.write(gildong.age); // 15
- 위의 에서는 gildong 객체에 changeAge라는 프로퍼티를 추가할 때 set 키워드를 사용하여 setter 메서드를 정의
- 따라서 해당 프로퍼티의 값을 변경하려고 할 때는 내부적으로 미리 정의한 setter 메서드가 자동으로 호출
정리하다 보니 객체가 생각보다 양이 많다.. ㄷㄷㄷ
다음시간엔 객체(3)으로 전역객체 / 래퍼객체 / 표준 객체에 대해 정리해 보겠다!
객체의 전반적인 기본 개념을 보시려면 "객체(1)" ← ← 포스팅을 참고해 주세요!!
끝!
Reference
https://www.tcpschool.com/javascript/js_object_prototype
'IT > Javascript' 카테고리의 다른 글
Javascript Array 객체 Object (0) | 2023.06.14 |
---|---|
Javascript 객체 Object 전역객체(global object), 래퍼객체(wrapper object), 객체 메서드 (0) | 2023.06.12 |
Javascript 객체 Object 참조 및 생성 (0) | 2023.04.28 |
Javascript 함수 function 정의 및 종류 (0) | 2023.04.21 |
Javascript 배열 Array 사용법 (0) | 2023.04.18 |