TIL. NO8. JAVASCRIPT(7)_객체지향

유자탱자🍋·2021년 1월 30일
0

1. 객체 지향 프로그래밍(Object Oriented Programming/ OOP)

객체 = 언어 차원에서 제공되는 문법적인 기능

하나의 객체 안에는 그 객체가 가지고 있는 취지, 혹은 기능과 연관되어있는 변수와 메소드가 담겨 있고 서로 연관성이 없는 다른 로직과 구분해주는 역할을 함.
또한, 이미 사용하고 있는 로직을 다른 곳에 사용하는 '재활용성'에도 기여함.
즉, 객체는 변수와 메소드를 grouping한 것.

  • 추상화(abstract) = 해결해야 할 문제, 혹은 반영해야 할 현실을 소프트웨어적으로 단순화시켜 만드는 행위
  • (재활용이 가능하도록) 부품화

    • 객체 지향은 부품화의 정점
  • 은닉화/캡슐화 = 내부의 동작 방법을 단단한 케이스(객체) 안으로 숨기고, 사용자에게는 그 부품(메소드)의 사용방법만을 노출하는 것.
    즉, 객체가 어떻게 만들어졌는지 몰라도 객체를 사용할 수 있도록 하는 것.

  • 인터페이스 = 부품들 간의 약속. 이질적인 것들이 결합하는 것을 막아주는 역할도 함.

    • ex. 모니터와 컴퓨터를 연결하는 케이블의 규격은 표준화되어 있음. 케이블의 연결점 모양을 표준에 맞게 만들면 되고, 이러한 연결점을 인터페이스라고 함.

2. 생성자와 new

자바스크립트 > Prototype-based programming

var person = {}
person.name = 'egoing';
person.introduce = function(){
  return 'My name is' + this.name;
}
document.write(person.introduce());

name, introduce : 변수/프로퍼티(property)/속성
function() : 메소드(method)

객체를 정의할 때 값을 세팅하도록 코드를 변경하면,

var person = {
    'name' : 'egoing',
    'introduce' : function(){
        return 'My name is '+this.name;
    }
}
document.write(person.introduce());
  • 생성자(constructor) = 객체를 만드는 역할을 하는 함수

    • 함수를 호출할 때 new를 붙이면 새로운 객체를 만든 후에 이를 리턴한다.

      function Person(){}
      var p0 = Person(); 
      p0 // undefined
      
      function Person(){}
      var p = new Person();
      p // Person{}
      
function Person(name){
    this.name = name;
    this.introduce = function(){
        return 'My name is '+this.name; 
    }   
}
var p1 = new Person('egoing');
document.write(p1.introduce()+"<br />");
 
var p2 = new Person('leezche');
document.write(p2.introduce());
  • 생성자의 역할 : 객체에 대한 초기화(Initialize).
    생성자가 만들어둔 빈 객체가 어떠한 프로퍼티/메소드를 가져야 되는지를 생성자 함수 내 기술하는 것을 통해서 그 객체가 가지고 있는 정보, 또 그 객체가 할 수 있는 일을 세팅. 따라서, 코드의 재사용성이 대폭 높아지게 됨.

3. 전역객체

자바스크립트에서 모든 객체는 기본적으로 전역객체의 프로퍼티

function func(){
    alert('Hello?');    
}
func(); // Hello?
window.func(); // Hello?

모든 전역변수와 함수는 사실 window 객체의 프로퍼티다. 객체를 명시하지 않으면 암시적으로 window의 프로퍼티로 간주된다.

호스트환경에 따라 전역객체의 이름/전역객체의 메소드 존재 유무가 달라진다.

이를테면 웹브라우저 자바스크립트에서는 alert()이라는 전역객체의 메소드가 존재하지만 node.js에는 존재하지 않는다. 또한 전역객체의 이름도 호스트환경에 따라서 다른데, 웹브라우저에서 전역객체는 window이지만 node.js에서는 global이다.


4. this

⭐️ this : 함수를 어떻게 호출하느냐에 따라서 this가 가리키는 대상이 달라진다

function func(){
    if(window === this){
        document.write("window === this");
    }
}
func(); 
// window === this

객체의 소속인 메소드의 this는 그 객체를 가르킨다.
var o = {
    func : function(){
        if(o === this){
            document.write("o === this");
        }
    }
}
o.func();  
// o === this

생성자는 빈 객체를 만든다. 그리고 이 객체 내에서 this는 만들어진 객체(o2)를 가르킨다
var funcThis = null; 
 
function Func(){
    funcThis = this;
}
var o1 = Func();
if(funcThis === window){
    document.write('window <br />');
}
 
var o2 = new Func();
if(funcThis === o2){
    document.write('o2 <br />');
}
// window, o2

function sum(x,y){return x+y;} >> 함수 리터럴
=
var sum = new Function('x', 'y', 'return x+y;'};

var o = {}
var p = {}
function func(){
    switch(this){
        case o:
            document.write('o<br />');
            break;
        case p:
            document.write('p<br />');
            break;
        case window:
            document.write('window<br />');
            break;          
    }
}

func(); // window
func.apply(o); // o
func.apply(p); // p

5. 상속(inheritance)

객체는 연관된 로직들로 이루어진 작은 프로그램이라고 할 수 있다. 상속은 객체의 로직을 그대로 물려 받는 또 다른 객체를 만들 수 있는 기능을 의미한다. 단순히 물려받는 것이라면 의미가 없을 것이다. 기존의 로직을 수정하고 변경해서 파생된 새로운 객체를 만들 수 있게 해준다.

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과 Person의 객체를 연결했더니 Programmer 객체도 메소드 introduce를 사용할 수 있게 되었다.
Programmer가 Person의 기능을 상속하고 있는 것이다. 단순히 똑같은 기능을 갖게 되는 것이라면 상속의 의의는 사라질 것이다. 부모의 기능을 계승 발전할 수 있는 것이 상속의 가치다.

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('egoing');
document.write(p1.introduce()+"<br />");
document.write(p1.coding()+"<br />");

// My name is egoing
   hello world

6. prototype(=객체의 원형)

객체는 프로퍼티를 가질 수 있는데 prototype이라는 프로퍼티는 그 용도가 약속되어 있는 특수한 프로퍼티다. prototype에 저장된 속성들은 생성자를 통해서 객체가 만들어질 때 그 객체에 연결된다.

  • prototype chain = 객체와 객체를 연결하는 체인 역할

    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);
    //true

7. 표준 내장 객체의 확장(standard built-in object)

내장 객체 = 자바스크립트가 기본적으로 가지고 있는 객체
(ex. Object/Function/Array/String/Boolean/Numer/Math/Date/RegExp)

<-> 사용자 정의 객체


8. Object 객체

object 객체는 객체의 가장 기본적인 형태를 가지고 있는 객체. 즉, 아무것도 상속받지 않는 순수한 객체

  1. object 객체가 가지고 있는 prototype은 모든 객체가 사용할 수 있는 기능
  2. 모든 객체가 가지고 있었으면 하는 기능이 있다면, object prototype에 기능을 추가
  • Object.prototype.~ = 모든 객체들이 상속받고 있는 공통의 기능

    Object 객체는 확장하지 않는 것이 바람직하다. 왜냐하면 모든 객체에 영향을 주기 때문이다.

    Object.prototype.hasOwnProperty() = 인자로 전달된 어떠한 값이 객체의 속성인지 여부를 판단


9. 데이터 타입

원시(기본) 데이터 타입 vs. 객체(참조) 데이터 타입

문자열과 같은 원시 데이터 타입은 객체로서 사용할 때 임시로 객체로 만들어준다.

  • 레퍼 객체(wrapper object) = 문자열과 관련해서 필요한 기능성을 객체지향적으로 제공해야 하는 필요 또한 있기 때문에 원시 데이터 형을 객체처럼 다룰 수 있도록 하기 위한 객체를 자바스크립트는 제공하고 있다.

ex. 숫자 > number, 문자열 > string, true/false > Boolean, null > X, undefined > X)


10. 참조

[변수에 담긴 값이 원시 데이터 타입일 경우]

var a = 1;
var b = a;
b = 2;
console.log(a); // 1

[변수에 담긴 값이 객체(참조 데이터 타입)일 경우]

var a = {'id':1};
var b = a;
b.id = 2;
console.log(a.id);  // 2

var a = {'id':1};
function func(b){
    b = {'id':2};
}
func(a);
console.log(a.id);  // 1
var a = {'id':1};
function func(b){
    b.id = 2;
}
func(a);
console.log(a.id);  // 2

0개의 댓글