티스토리 뷰

do/javascript

javascript 3

dooo.park 2019. 4. 29. 10:17

객체지향 프로그래밍(OOP : Object-Oriented Programming)

프로그래밍 패러다임으로 로직을 상태(state)와 행위(behave)로 이루어진 객체로 만드는 것

객체들을 조립해서 하나의 프로그램을 만드는 것이 객체지향 프로그래밍이다.

 

은닉화(Information Hiding) / 캡슐화(Encapsulation)

내부 동작 방법을 숨기고 사용자에게는 사용방법만을 노출하는 것

 

생성자(constructor)

객체를 만드는 역할을 하는 함수

function Person(){}
var p = new Person();
p.name = 'aa';
p.introcduce = function(){
    return 'my name is '+this.name;
}
document.write(p.introduce());

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

function Person(name){
    this.name = name;
    this.introduce = function(){
        retirm 'my name is ' + this.name;
    }
}
var p1 = new Person('aa');
document.write(p1.introduce());
var p2 = new Person('bb');
document.write(p2.introduce());

생성자 내에서 이 객체의 프로퍼티를 정의하고 있다. 이를 초기화라고 한다. 코드의 재사용성이 높아졌다.

 

전역객체(Global object)

모든 객체는 이 전역객체의 프로퍼티다.

function func(){
    alert('hello?');
func();
window.func();

func();와 window.func();는 모두 실행 된다.

모든 전역변수와 함수는 사실 window 객체의 프로퍼티다.

객체를 명시하지 않으면 암시적으로 window의 프로퍼티로 간주된다.

var o = {'func':function(){
    alert('hello?');
}}
o.func();
window.o.func();

자바스크립트에서 모든 객체는 기본적으로 전역객체의 프로퍼티임을 알 수 있다.

 

전역객체 API

ECMAscript에서는 전역객체의 api를 정의해두었다.

그 외의 api는 호스트 환경에 따라 추가로 정의하고 있다.

예를 들어 웹브라우저 자바스크립트에서는 alert()라는 전역객체의 메소드가 존재하지만,

node.js에는 존재하지 않는다.

전역객체의 이름도 호스트환경에 따라 다른데 웹브라우저에서 전역객체는 window이지만

node.js에서는 global이다.

 

this

this는 함수 내에서 함수 호출 맥락(context)를 의미한다.

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

함수와 객체의 관계가 느슨한 자바스크립트에서 this는 이 둘을 연결해주는 역할을 한다.

 

함수호출

함수를 호출했을 때 this는 전역객체인 window와 같다.

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

생성자의 호출

아래는 함수를 호출했을때와 new를 이용해서 생성자를 호출했을 때의 차이이다.

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

생성자는 빈 객체를 만든다. 이 객체 내에서 this는 만들어진 객체를 가르킨다.

생성자가 실행되기 전까지는 객체는 변수에도 할당될 수 없기 때문에 this가 아니면 객체에 대한 어떤 작업도 할 수없다.

function Func(){
    document.write(o);
}
var o = new Func();

// undefined

apply, call

함수의 메소드인 apply와 call을 이용하면 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);

// window
// o
// p

상속(inheritance)

상속은 객체의 로직을 그대로 물려받는 또 다른 객체를 만들 수 있는 기능을 의미한다.

function Person(name){
    this.name = name;
}
Person.prototype.name = null;
Person.prototype.introduce = function(0{
    return 'my name is' + this.name;
}

function Programmer(name){
    this.name = name;
}
Programmer.prototype = new Person();

var p1 = new Programmer('aa');
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('aa');
document.write(p1.introduce()+"<br />");
document.write(p1.coding()+"<br />");

// my name is aa
// hello world

Programmer는 Person의 기능을 가지고 있으면서 Person이 가지지 않은 기능인 

메소드 coding을 갖고 있다.

 

Protytype

함수는 객체이다. 따라서 생성자로 사용되는 함수도 객체이다.

객체는 프로퍼티를 가질 수 있는데 prototype이라는 프로퍼티는 그 용도가 약속되어있는 특수한 프로퍼티다.

prototype에 저장된 속성들은 생성자들을 통해 객체가 만들어질 때 그 객체에 연결된다.

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

생성자 Sub를 통해 만들어진 객체 o가 Ultra의 프로퍼티 ultraProp에 접근가능한 것은

prototype체인으로 Sub와 Ultra가 연결되어 있기 때문이다.

 

1. 객체 o에서 ultraProp을 찾는다.

2. 없다면 Sub.prototype.ultraProp을 찾는다.

3. 없다면 Super.prototype.ultraProp을 찾는다.

4. 없다면 Ultra.prototype.ultraProp을 찾는다.

 

prototype이 객체와 객체를 연결하는 체인의 역할을 한다. 이를 prototyte chain이라 한다.

 

표준 내장 객체의 확장(Standard Built-in Object)

자바스크립트가 기본적으로 가지고 있는 객체들이다.

Object / Function / Array / String / Boolean / Number / Math / Date / RegExp

 

배열 확장

var arr = new Array('seoul', 'newyork', 'ladarkh', 'pusan', 'tsukuba');
function getRamdomValueFromArray(haystack){
    var index = Math.floor(haystack.length * Math.random());
    return haystack[index];
}
console.log(getRandemValueFromArray(arr));

위에서 함수를 배열 객체이 포함시키면 배열에 내장된 메소드처럼 사용할 수 있다.

Array.prototype.rand = function(){
    var index = Math.floor(this.length * Math.random());
    return this[index];
}
var arr = new Array('seoul', 'newyork', 'ladarkh', 'pusan', 'tsukuba');
console.log(arr.rand());

 

Object

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

자바스크립트에서는 값을 저장하는 기본단위로 Object를 사용한다.

동시에 모든 객체는 Object를 상속받고 Object 객체의 프로퍼티를 가지고 있다.

 

Object 객체를 확장하면 모든 객체가 접근할 수 있는 api를 만들 수 있다.

Object.prototype.contain = function(neddle){
    for(var name in this){
        if(this[name] === neddle){
            return true;
        }
    }
    return false;
}
var o = {'name':'aa', 'city':'seoul'};
console.log(o.contain('aa'));
var a = ['aa', 'bb', 'cc'];
consloe.log(a.contain('bb'));

Object 객체는 모든 객체에 영향을 주기 때문에 확장하지 않는 것이 좋다.

for(var name in o)P
    if(o.hasOwnProperty(name))
        console.log(name);
}

hasOwnProperty로 프로퍼티의 해당 객체의 소속인지 체크해 볼 수 있다.

인자로 전달된 속성의 이름이 객체의 속성인지 여부를 판단한다. 만약 prototype으로 상속받은 객체라면 false가 된다.

 

데이터 타입

데이터 타입은 객체와 객체가 아닌것으로 나눌 수 있다.

그 중 객체가 아닌 데이터 타입을 원시 데이터 타입(primitive type)이라 한다. 이들 이외의 타입은 모두 객체다.

숫자 / 문자열 / boolean(true, false) / null / undefined

 

레퍼 객체(wrapper object)

원시 데이터형을 객체처럼 다룰 수 있도록 하기 위한 객체

String / Number / Boolean (null과 undefined는 래퍼 객체가 존재하지 않음)

 

참조(reference)

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

변수 b에 담긴 객체의 id값을 2로 변경했는데 a.id의 값도 2가 되었다.

변수 b와 변수 a에 담긴 객체가 서로 같다는 것을 의미한다.

원본을 복제한 것이 아니라 참조하고있는 것이다.

 

자바스크립트에서 원시데이터형을 제외한 모든 데이터 타입은 객체다.

객체를 다른말로 참조데이터 형(참조 자료형)이라고도 부른다. 

기본데이터형은 복제되지만 참조데이터형은 참조된다.

 

변수에 담겨있는 데이터가 원시형이면 그 안에는 실제 데이터가 들어있고,

객체면 변수 안에는 데이터에 대한 참조방법이 들어있다.

 

재귀함수

함수가 자기 자신을 호출하는 것

<!DOCTYPE html>
<html>
<body id="start">
<ul>
    <li><a href="./532">html</a></li> 
    <li><a href="./533">css</a></li>
    <li><a href="./534">JavaScript</a>
        <ul>
            <li><a href="./535">JavaScript Core</a></li>
            <li><a href="./536">DOM</a></li>
            <li><a href="./537">BOM</a></li>
        </ul>
    </li>
</ul>
<script>
function traverse(target, callback){
    if(target.nodeType === 1){
        //if(target.nodeName === 'A')
        callback(target);
        var c = target.childNodes;
        for(var i=0; i<c.length; i++){
            traverse(c[i], callback);       
        }   
    }
}
traverse(document.getElementById('start'), function(elem){
    console.log(elem);
});
</script>
</body>
</html>

 

 


참고

https://www.opentutorials.org/course/743/

'do > javascript' 카테고리의 다른 글

javascript 2  (0) 2019.04.26
javascript 1  (0) 2019.04.25
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
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 31
글 보관함