[JavaScript] 객체지향

이예지·2023년 9월 21일

JavaScript

목록 보기
4/4
post-thumbnail

❓ 객체지향프로그래밍 OOP

OOP : Object Oriented Programming
객체 : 연관성있는 변수(상태)와 메소드(행위)를 그룹핑한 것

연관성이 떨어지거나 연관이 없는 것들은 객체라는 껍데기로 분류할 수 있는 것
이렇게 연관되는 변수와 메소드들을 묶어 하나의 기능을 하는 객체를 만들 게 되면, 이 객체를 다른 애플리케이션 등에서도 가져다 쓸 수 있게 된다. 이것이 객체가 재활용성에 기여하는 바라고 할 수 있다.

💥 추상화 (abstract)

복잡한 현실을 상대적으로 단순한 프로그램으로 만들어야하기 때문에 추상화를 거쳐야한다. 예를 들면 복잡한 현실 지리를 간단하게 만든 '지하철 노선도'는 지하철이라는 대상에 집중하여 어떠한 목적을 가지고 추상화한 것이다.
추상화 : 해결해야할 문제, 반영해야할 현실을 SW적으로 단순화시켜서 만드는 행위

💥 부품화

본체,키보드,모니터가 단일화되어있던 초창기의 컴퓨터에서 현재는 기능들을 기준으로 본체, 키보드, 모니터로 분리시켜 소비자들은 더 좋은 키보드나 저렴한 모니터를 선택할 수 있게 되었으며, 문제가 생겼을 때 그 문제가 어디에서 발생한 것인지 파악하고 해결하기가 훨씬 쉬워졌다.

💥 은닉화,캡슐화

제대로된 부품이라면 그 부품이 만들어진 방법을 몰라도, 사용자가 그 부품을 사용할 수 있어야 한다. 객체라는 부품 안에 내부 동작 방법을 숨기고, 사용 방법인 메소드만 노출하는 것을 정보의 은닉화, 캡슐화라고 한다.

⚡️ 생성자와 new

자바스크립트는 prototype-based programming을 지향한다.

💡 객체

객체 : 서로 연관된 변수와 함수를 그룹핑한 그릇
property(속성) : 객체 내의 변수
method : 객체의 property가 갖는 함수
생성자(constructor) : 객체를 만드는 역할을 하는 함수

function Person(){}
var p = new Person(); // 이때 Person()이 생성자
p.name = 'egoing';
p.introduce = function(){
    return 'My name is '+this.name; 
}
document.write(p.introduce());

자바에서는 클래스 안에 생성자가 존재하고, 생성자를 통해 클래스의 객체를 만들어낸다. 그러나 자바스크립트에서는 '클래스'라는 존재가 존재하지 않고, 생성자를 통해 함수의 객체를 만들어낸다.

function Person(){}
var p1 = new Person();
p1.name = 'egoing';
p1.introduce = function(){
    return 'My name is '+this.name; 
}
document.write(p1.introduce()+"<br />");
 
var p2 = new Person();
p2.name = 'leezche';
p2.introduce = function(){
    return 'My name is '+this.name; 
}
document.write(p2.introduce());

해당 코드의 문제점은 중복되늖 함수를 introduce 속성에 담는 것이다. 따라서 다음과 같이 개선할 수 있다.

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

생성자는 객체에 대한 초기화(init) 역할을 해준다.

⚡️ 전역객체

모든 객체는 전역객체의 property이다.
func() = window.func()
즉, 모든 전역변수와 함수는 window 객체의 property이다.
전역객체 API 보기

⚡️ this

this는 함수 내에서 함수 호출 맥락(context)를 의미한다. 맥락이라는 것은 상황에 따라서 달라진다는 의미인데 즉 함수를 어떻게 호출하느냐에 따라서 this가 가리키는 대상이 달라진다는 뜻이다. 함수와 객체의 관계가 느슨한 자바스크립트에서 this는 이 둘을 연결시켜주는 실질적인 연결점의 역할을 한다.

함수를 호출했을 때 this === window
메소드를 호출했을 때 this === 메소드가 소속되어있는 객체

var funcThis = null; 
 
function Func(){
    funcThis = this;
}

// 여기서 o1의 this는 window를 나타낸다.
var o1 = Func();
if(funcThis === window){
    document.write('window <br />');
}
 
// 여기서 o2의 this는 만들어진 객체 o2를 의미한다.
var o2 = new Func();
if(funcThis === o2){
    document.write('o2 <br />');
}

💡 객체로써의 함수

function sum(x,y){return x+y;}

===
 
var sum = new Function('x','y','return x+y;');

⚡️ 상속

생성자에 의해 객체가 만들어질 때, 생성자에게 prototype이라는 property가 있는지 확인하고, 만약 있다면 생성자 함수 안에 있는 객체와 똑같은 객체를 만들어 생성자의 결과로 return을 해준다.

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

여기서 name이라는 property와 introduce라는 메소드를 가지고 있는 객체가 prototype 안에 있으므로, new Person()을 하면 똑같이 name과 introduce를 갖는 객체를 상속하는 것이다.
p1은 prototype이라고 하는 생성자의 property에 들어있는 객체와 같은데, 그 객체는 new Person 즉, 위의 Person 생성자로 만든 객체이기 때문에 이 객체가 가진 introduce라는 메소드도 가지는 것!
상속하여 만든 객체에 prototype.원하는 property로 새로운 기능을 추가할 수도 있다.
어렵지만 차근히 읽어보자 ...

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

최상위 Ultra - Super - Sub 최하위

prototype이라는 property 안에 객체를 만들고 저장해두었다가, new로 생성하게 되면 prototype property 안에 있는 객체를 꺼내와 상속받는 것!

prototype chain.. 어렵다

⚡️ 표준 내장 객체

표준 내장 객체(Standard Built-in Object) : 자바스크립트가 기본적으로 제공하는 객체 (↔ 사용자 정의 객체)
자바스크립트 표주 내장 객체 종류

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

➡️ 표준내장객체 Array의 사용

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.random() : Math.random()이 0부터 1 사이의 수를 랜덤하게 리턴하므로, 어떤 값을 곱했을 때 0부터 그 값 사이의 수를 랜덤하게 얻을 수 있다.
Math.floor() : 소숫점 아래 수를 없애준다.

➡️ Array와 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());

⚡️ Object

Object는 객체의 가장 기본적인 형태를 가지고 있는 객체이다. Object의 property는 모든 객체들이 갖는 property가 되는 것이다.

// 객체 안에 인자로 받은 이름과 같은 이름이 있다면 true를 리턴
Object.prototype.contain = function(neddle) {
    for(var name in this){
        if(this[name] === neddle){
            return true;
        }
    }
    return false;
}
var o = {'name':'egoing', 'city':'seoul'}
console.log(o.contain('egoing'));
var a = ['egoing','leezche','grapittie'];
console.log(a.contain('leezche'));

⚡️ 데이터 타입

데이터 타입 : 데이터의 형태
원시 데이터 타입(primitive data type)이 아닌 데이터 타입은 모두 객체이다.

원시 데이터 타입   객체가 아닌 데이터 타입

  • 숫자
  • 문자열
  • 불리언(true/false)
  • null
  • undefined

💥 레퍼 객체

var str = 'coding';
console.log(str.length);        // 6
console.log(str.charAt(0));     // "C"

이때 문자열에는 메소드와 프로퍼티가 존재하지만, 문자열을 객체가 아니다.
자바스크립트에서는 문자열과 관련된 어떤 작업을 하려고 할 때 자바스크립트는 임시로 문자열 객체를 만들고 사용이 끝나면 제거하기 때문이다.

var str = 'coding';
str.prop = 'everybody';
console.log(str.prop);      // undefined

이렇게 prop이라는 프로퍼티를 생성할 수는 있지만 바로 제거되기 때문에, str.prop을 하는 순간에는 undefined로 나타난다.

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

레퍼 객체 (Wrapper Object)

  • String
  • Number
  • Boolean

⚡️ 참조

🆚 복제 vs 참조

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

위 예제에서는 b가 a를 참조하고 있지만, b에 새로운 객체 {'id':2}를 할당했으므로 a와 같은 객체를 가리키던 링크가 끊어지게 된다. 따라서, a를 호출해도 값은 바뀌지 않은 것을 확인할 수 있다.

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

위 예제는 b가 a를 참조하고, property에 접근하여 값을 바꾸고 있으므로, a를 호출하면 값이 바뀐 것을 확인할 수 있다.






참고

인프런-생활코딩 자바스크립트(JavaScript) 기본
https://opentutorials.org/course/743/4650

0개의 댓글