섹션 22. 객체지향 - 상속
1강. 상속이란?
상속(inheritance)
객체지향에서 아주 중요한 개념
객체의 로직을 그대로 물려받는 또 다른 객체를 만드는 기능을 의미한다. 다만, 그대로 물려받는 것이 아니라 기존 로직을 수정하고 변경한 파생된 새로운 객체를 만들게 해 준다.
로직 재활용 가능
//original
function Person(name) {
this.name = name;
this.introduce = function() {
return 'My name is ' +this.name;
}
}
var p1 = new Person('innovation');
document.write(p1.introduce()+"<br />");
function Person(name) {
this.name = name;
}
Person.prototype.name=null;
Person.prototype.introduce = function(){
return 'My name is '+this.name;
}
var p1 = new Person('innovation');
document.write(p1.introduce()+"<br />");
상속하기 전 코드
2강. 상속의 사용법
function Person(name){
this.name = name;
}
Person.prototype.name=null;
Person.prototype.introduce = function(){
return 'My name is '+this.name;
}
function Programmer(name){
this.name = name;
}
Programmer.prototype = new Person();
var p1 = new Programmer('egoing');
document.write(p1.introduce()+"<br />");
상속이 일어난 코드.
객체를 상속받고 싶다면, 객체를 생성자의 프로토타입에 할당을 시키면 된다.
Programmer.prototype = new Person();
사용법의 핵심은 이것
원리를 100% 이해 못 하더라도 사용법을 알면 쓸 수 있기 때문에 사용법 위주로 기억한다.
3강. 기능의 추가
핵심 역할 : prototype
객체, 함수에서 매우 중요한 기능
prototype based language라고 불릴 정도
function Person(name) {
this.name = name;
}
Person.prototype.name=null;
Person.prototype.introduce = function(){
return 'My name is '+this.name;
}
function Programmer(name){
this.name = name;
}
Programmer.prototype = new Person();
Programmer.prototype.coding = function(){
return "hello world^_^~";
}
var p1 = new Programmer('innovation');
document.write(p1.introduce()+"<br />");
document.write(p1.coding()+"<br />");
위의 코드를 수정해서 추가하면 다음과 같이 활용할 수 있다.
챗GPT의 도움을 받지 않고 한 거라 뿌듯했다!
function Person(name) {
this.name = name;
}
Person.prototype.name=null;
Person.prototype.introduce = function(){
return 'My name is '+this.name;
}
function Programmer(name){
this.name = name;
}
Programmer.prototype = new Person();
Programmer.prototype.coding = function(){
return "hello world^_^~";
}
function Designer(name){
this.name = name;
}
Designer.prototype = new Person();
Designer.prototype.design = function(){
return "Beautiful!";
}
var p1 = new Programmer('innovation');
document.write(p1.introduce()+"<br />");
document.write(p1.coding()+"<br />");
var p2 = new Designer('Im');
document.write(p2.introduce()+"<br />");
document.write(p2.design()+"<br />");
4강. prototype ★★★
객체지향을 지탱하고 있는 핵심적인 기능
JavaScript를 일반적인 객체지향 언어와 구분하는 아주 중요한 기능
원형(prototype)
ultraProp이 나올 때까지 위를 탐색함
탐색의 결과, true의 값을 얻음
생성자로 함수를 생성하는 이유 var o = new Sub ( ) ;
우리가 어떤 객체를 만들 때, 객체가 가지고 있어야 되는 매소드나 프로퍼티를 기본적으로 가지고 우리에게 주어지기를 바란다. 객체 안에 로직과 데이터가 담겨있기 때문. 비어 있는 것은 소용이 없기 때문에 var o = { }; 처럼 생성하지 않는다.
객체의 원형이 어디에 저장되어 있는가?
prototype에 저장되어 있는 것.
겉에서 봤을 때는 티가 안 날 수 있지만 속에서는 prototype에 객체가 저장되고 있다.
5강. prototype chain
자식에 기능을 추가하면 부모에 기능을 추가하는 것과 동일한 효과를 낸다.
자식에게 일어나는 일이 부모에게 반영된다. 그런 문제가 발생할 수 있다. 그래서 프로토타입을 그대로 쓰는 것이 아니라 프로토타입의 복제본을 사용해야 한다. (예 : Sub.property = new Super () )
function Ultra(){}
Ultra.prototype.ultraProp = true;
function Super(){}
Super.prototype = new Ultra();
function Sub(){}
Sub.prototype = new Super();
var o = new Sub();
console.log(o.ultraProp);
document.write(o.ultraProp);
섹션 23. 객체지향 - 표준 내장객체의 확장
1강. 표준 내장 객체란?
표준 내장 객체(Standard Built-in Object)
자바스크립트가 기본적으로 가지고 있는 객체들을 의미한다. 공식적으로 기본적(Standard)으로 탑재(Built-in)되는 객체들이다. 그렇게 많지는 않다.
- Object
- Function
- Array
- String
- Boolean
- Number
- Math
- Date
- RegExp
- 우리가 필요한 기능이 없다면 우리가 정의해서 사용할 수 있다.
- 사용자 정의 객체(표준 내장 객체와 대비되는 개념)
2강. 배열의 확장1
var arr = new Array('seoul','new york','ladarkh','pusan', 'Tsukuba');
function getRandomValueFromArray(haystack){
var index = Math.floor(haystack.length*Math.random());
return haystack[index];
}
console.log(getRandomValueFromArray(arr));
Math.floor : 소수점 이하 버림
Math.random : 0~1 사이에 random 한 숫자
3강. 배열의 확장2
내장 객체 prototype을 이용하여 배열을 확장
Array.prototype.rand = function(){
var index = Math.floor(this.length*Math.random());
return this[index];
}
var arr = new Array('seoul','new york','ladarkh','pusan', 'Tsukuba');
console.log(arr.rand());
this가 arr이 된다.
2강의 예제에서 나온 getRandomValueFromArray라는 근본 없는 함수가 arr.rand로 바뀜
rand라는 함수가 Array.prototype.rand=function ( ) 라는 함수로 정의됨으로써 Array에 속한다는 것과, 인자를 따로 지정하지 않는다는 것이 장점이다.
즉, 코드의 가독성이 높아지는 것이다.
섹션 24. 객체지향 - Object
1강. Object란?
Object
- 데이터를 저장하는 그릇
- 가장 기본적인 형태를 가지고 있는 객체
- 아무것도 상속받지 않는 순수한 객체
- 값을 저장하는 기본적인 단위
- object 객체의 prototype는 모든 객체의 프로토타입, 원형이 된다.
2강. Object API 사용법
https://developer.mozilla.org/ko/
1) object.keys
object를 value 말고 key값을 배열로 만들어서 return 하는 메서드
위에서 key만 return 한다.
2) toString
객체가 담고 있는 값이 무엇인가를 사람이 보기 좋게 출력해 주는 것
배열이 담고 있는 값만을 출력해 준다.
객채의 값이나 상태를 사람이 보기 편하게 출력해 주는 것
//Object.keys()
var arr = ["a", "b", "c"];
console.log('Object.keys(arr)', Object.keys(arr));
//Object.prototype.toString()
var o = new Object();
console.log('o.toString()', o.toString());
var a = new Array(1,2,3);
console.log('a.toString()', a.toString());
Object.keys = function ( ) { }
생성자 함수
Object : 모든 객체의 부모
위에서 Array도 Object를 부모로 하는 객체가 된다.
그래서 Array를 통해서 만들어진 객체는 객체.toString을 통해서 Object에 정의되어 있는 메서드를 사용할 수 있다는 것이다.
Object.prototype.toString = function ( ) { }
매소드가 프로토타입 소속이다?
new Object( ); 를 실행시키는 순간에 객체를 만들고, 프로토타입이라고 하는 특수한 프로퍼티에 저장되어 있는 객체를 원형으로 하는 객체를 생성하는 것. 그 객체는 toString을 사용할 수 있다. toString은 객체에 대한 메서드로 사용한다.
3강. Object의 확장
내가 만드는 것이 어떻게 사용될까를 충분히 고민한 후에 구현하는 게 사용성이 좋게 된다.
기능을 볼 때도 원리부터 파악하기보다는 어떻게 사용하는지를 먼저 파악하는 것이 중요하다. 원리는 그다음이다.
Object 객체를 확장하면 모든 객체가 접근할 수 있는 API를 만들 수 있다.
Object.prototype.contain = function(neddle) {
for(var name in this){
if(this[name] === neddle){
return true;
}
}
return false;
}
var o = {'name':'paradigm', 'city':'seoul'}
console.log(o.contain('paradigm'));
var a = ['paradigm','innovation','career'];
console.log(a.contain('career'));
4강. Object 확장의 위험
이런 확장을 하는 이유는 모든 객체에 영향을 줄 수 있기 때문인데, 반대로 이런 확장이 위험한 이유도 모든 객체에 영향을 미칠 수 있기 때문이다.
Object에 프로퍼티나 메서드를 추가하는 것은 매우 신중해야 하는 일이다.
for(var name in o){
console.log(name);
}
contain은 들어가면 안 되는데 자신이 있을 자리처럼 자리 잡고 있다.
들어가길 바라는 객체 외에 다른 객체가 있다면 매우 혼란스럽다.
이때, 프로퍼티가 객체의 소속인지를 확인할 수 있는 hasOwnProperty를 사용하면 된다.
for(var name in o){
if(o.hasOwnProperty(name))
console.log(name);
}
hasOwnProperty를 사용하면 다음과 같이 나온다.
hasOwnProperty는 인자로 전달된 속성의 Name이 객체의 속성인지를 판단한다.
만일, 프로토타입으로 상속받은 객체라면 false가 된다.