< 자바스크립트(JavaScript) ; 객체지향 >

 

1. 객체지향 프로그래밍

 

1) 객체지향 프로그래밍

 - OOP : Object Oriented Programming, 로직을 상태(state)와 행위(behavier)로 이루어진 객체(변수,메소드 등)로 만드는 것.

2) 특징 : 추상화, 부품화, 은닉화, 캡슐화, 인터페이스(부품과 부품의 교환 기능, 부품 규격의 표준화)

 

2. 객체지향-생성자와 new

 

1) 자바스크립트의 객체지향

 - 자바스크립트 언어는 prototype-based-programming 언어에 속함.

 - 객체 : 서로 연관된 변수와 함수를 그룹핑한 그릇

 - 객체 내의 변수는 property, 객체 내의 함수는 method

 

2) 객체 생성

 - 빈 객체 만든 후 객체 값 정의

var person = {}

person.name = 'aaa';

person.introduce = function(){

    return 'My name is '+this.name;

}

document.write(person.introduce());

 - 객체를 생성하면서 값 세팅

var person = {

    'name' : 'aaa',

    'introduce' : function(){

        return 'My name is '+this.name;

    }

}

document.write(person.introduce());

 - 다른 사람의 이름을 담을 객체가 필요하면 위에 사용된 객체 정의를 반복해야 하는데, 이 때 생성자를 이용하여 객체 구조를 재활용 가능함.

 

3) 생성자와 new

 - 생성자(constructor)는 객체는 만드는 역할을 하는 함수

 - 자바스크립트에서 함수는 단순히 재사용 가능한 로직의 묶음이 아니라 객체를 만드는 창조자라고 할 수 있음.

 - 함수 앞에 new를 붙여서 변수(객체)에 담으면, 그 함수는 객체의 창조자(생성자)가 되며, 기존 함수가 복제된 동일한 기능을 가지는 새로운 객체를 생성하게 됨. (파이썬의 클래스의 인스턴스 개념인 듯, 자바스크립트에는 클래스의 개념이 없음.)

 - 생성자(함수)의 역할 : 초기화(init, initialize, 객체에 대한 초기화)

function Person(name){

    this.name = name;

    this.introduce = function(){

        return 'My name is '+this.name;

    }  

}

var p1 = new Person('aaa');

document.write(p1.introduce()+"<br />");

 

var p2 = new Person('bbb');

document.write(p2.introduce());

 

3. 객체지향-전역객체

 - this를 이해하기 위해 필요한 기초 개념

 - 전역객체 : 특수한 객체, 자바스크립트의 모든 객체는 전역객체의 property .

 - function func(){

           alert('Hello?');

}

 - func();

 - window.func(); //전역객체 window는 생략 가능(암시적 사용)

 - func (웹브라우져 JS에서) window 전역객체의 property(method).

 - node.js 의 경우는 window가 아닌 global 이 전역객체임.

 

4. 객체지향-this

 

1) 함수와 this

 - this는 함수 내에서 함수 호출 맥락(context)을 의미하며, 이는 함수를 어떻게 호출하느냐에 따라서 this가 가리키는 대상이 달라진다는 의미임. 자바스크립트에서 this는 함수와 객체를 연결시켜주는 연결점의 역할을 함.

 - 함수에서 this는 전역객체인 window와 같음.

 - 함수에서 사용된 this는 함수가 소속된 객체를 가르킴.

 

2) 메소드와 this

 - 메소드에서 사용된 this는 메소드를 담고있는 객체를 가르킴.(함수의 this와 같은 의미)

 

3) 생성자와 this

 - 생성자에서 사용되는 this는 새로 생성되는 객체를 가르킴.

 - 함수가 함수로 사용되면 thiswindow를 가르키고, 함수에 new가 붙어 생성자로 사용되면 this는 생성자가 새로 만든(만들) 객체를 가르킴.

 

4) 객체로서의 함수

 - 함수의 메소드인 apply call 을 이용하면 this의 값을 제어할 수 있음.

 - 함수리터럴, 객체리터럴, 배열리터럴...(함수,객체,배열을 만드는 문법)

 

5) apply this

 - 함수의 소속(객체), 함수의 parameter가 정의되어 있지않고, 그 함수의 인자로 객체가 전달되었을 때, 함수에서 사용된 this는 함수의 인자로 전달된 객체를 의미함. (이 경우는 함수가 객체의 소속이 아니지만, 마치 그 객체의 소속인 것처럼 작동함.)

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();

func.apply(o);

func.apply(p);

 

* this는 함수, 메소드, 생성자, 객체 어디에서 사용되든 의미론적으로 this를 품고있는 객체를 가르킴!

 

5. 객체지향-상속

 

1) 상속(inheritance)

 - 부모를 상속받은 객체는 부모 객체의 변수와 메소드에 접근할 수 있음.

 - 자식 객체는 부모 객체의 변수, 메소드를 수정해서 사용할 수 있음.

 

2) 상속의 사용법

 - 상속 : Programmer.prototype = new Person();

 - 어떠한 객체를 상속받으려면, 생성자(programmer)prototype(property)에 상속대상 객체를 new 를 이용해서 할당시키면 됨.

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('aaa');

document.write(p1.introduce()+"<br />");

 

 

3) 기능 추가

Programmer.prototype = new Person();

Programmer.prototype.coding = function(){

    return "hello world";

}

 

var p1 = new Programmer('aaa');

document.write(p1.introduce()+"<br />");

document.write(p1.coding()+"<br />");

 

4) prototype(원형) and prototype chain

 - 객체는 property 를 가질 수 있으며, prototype 은 용도가 약속되어 있는 특수한 property.

 - 생성자 함수의 prototype 에 저장된 속성들은 생성자를 통해서 만들어지는 객체에 전달됨.

Super.prototype = new Ultra().prototype;

 --> 이런식으로 상속시키면 작동은 하는 것 같이 보이지만 자식의 prototype 속성을 수정하면 부모의 prototype 까지 변경이 발생하게됨. , 실직적인 상속 개념으로 사용할 수 없게됨. --> 따라서, 상속을 사용하려면 부모 객체 자신을 new를 이용해서 자식객체의 prototype에 할당하는 방법을 사용해야 함.

 - prototype chain

객체 o에서 ultraProp를 찾는다.

없다면 Sub.prototype.ultraProp를 찾는다.

없다면 Super.prototype.ultraProp를 찾는다.

없다면 Ultra.prototype.ultraProp를 찾는다.

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

 

6. 객체지향-표준 내장객체의 확장

 

1) 표준 내장 객체

 - 자바스크립트가 가지고 있는 표준 내장 객체(Stnadard Built-in Object)

  : Object, Function, Array, String, Boolean, Number, Math, Date, RegExp

 - 완전히 새로운 사용자 정의 객체를 생성할 수도 있지만, 내장 객체에 일부 수정을 가해서 사용자 정의 객체를 만들 수 있음. --> 배열 객체인 Array의 예를 살펴보자.

 

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

 

3) 배열의 확장2

 - rand : 입력받은 배열에서 무작위로 1개 요소를 추출하는 메소드

 - 자바스크립트이 내장함수 Arrayrand라는 메소드를 Arrayproperty(prototype)으로 추가해줌으로써 내장함수 Array의 속성(메소드)를 추가(변경)했음. --> 내장함수를 이용한 사용자 정의 함수(객체) 생성

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());

 

7. 객체지향-Object

 - object : 객체의 가장 기본적인 형태를 가지고 있는 객체, 아무것도 상속받지 않는 순수한 객체, 자바스크립트에서는 값을 저장하는 기본적인 단위( = 배열, array)

 - 자바스크립트의 모든 객체는 object 객체를 상속받으므로, 모든 객체는 object 객체의 property 를 가지게 됨(object 객체는 모든 객체의 부모). object 객체를 확장하면 모든 객체가 접근할 수 있는 API 를 만들 수 있음. object prototype에 특정 기능을 추가하면, 자바스크립트의 모든 객체가 그 기능을 사용할 수 있게됨. but, object prototypemethod 를 추가할 때는 매우 주의해야 함. (hasOwnProperty 구문을 사용하는게 비교적 안전함.)

for(var name in o){

    if(o.hasOwnProperty(name)){

        console.log(name);

    }

}

 - object.method() object.prototype.toString() 의 차이는? (Array = 배열(객체))

object.method() 사용 --> object.method(Array) //keys()

object.prototype.method() 사용 --> Array.method(). //toString()

 

8. 객체지향-데이터타입

 - 원시(기본) 데이터 타입(primative type) : 숫자, 문자열, Boolena(불리언), null, undefined

 - 객체(참조) 데이터 타입 : 원시 데이터 타입 외는 객체 데이터 타입

 - 레퍼객체(wrapper object) : 문자열은 프로퍼티와 메소드가 있는데 원시데이터 타입이고 객체는 아니다? 문자열에 대한 프로퍼티나 메소드 작업이 필요한 경우, 자바스크립트가 임시로 문자열 객체(레퍼객체 string이 문자열을 감싸서 임시 객체를 만들어 줌.)를 만들고 사용이 끝나면 제거함. 레퍼객체에는 프로퍼티를 저장할 수는 없음. (사용이 끝나면 다시 원시 객체로 변경됨.)

숫자, 문자열, 불리언에는 레퍼객체가 존재, null undefined 에는 레퍼객체가 존재하지 않음.

 

9. 객체지향-복제와 참조

 - 복제 : 변수 b의 값에 a의 값이 복제된 것임. b의 값을 변경해도 a의 값에는 영향 없음.

(변수 a에 담긴 값이 원시 데이터 타입일 때)

var a=1;

var b=a;

b=2;

console.log(a); //1

 - 참조(reference) : 변수 a에 담긴 값이 객체(배열)일 때. bid 값 변경은 aid 값도 변경시킴(원본 데이터가 객체인 경우는 참조관계). 윈도우의 바로가기 링크와 유사.

var a={'id':1};

var b=a;

b.id = 2; //b객체의 id 값을 변경

console.loa(a.id); //2

 - 복제와 참조 정리 : 변수에 담겨있는 데이터가 원시형이면 그 안에는 실제 데이터가 들어있고, 객체면 변수 안에는 데이터에 대한 참조 방법이 들어있는 것으로 볼 수 있음.

 - 아래 경우는 객체 참조가 아니고 b객체 생성

var a={'id':1};

var b=a;

b = {'id' : 2}; //b객체를 새로 생성

console.loa(a.id); //1

 - 함수와 참조 : function func(b){~~~}

--> func(a); //func에 파라미터 b 대신 파라미터 a를 넣어서 생각하면 안되고, b=a(파라미터 b에 인자 a값을 할당한 것으로 해석해야 함.)

 


+ Recent posts