Data Type, Constructor (객체 지향 1)

데이터 타입은 크게 두 가지로 Primitive와 Reference가 있다. Primitive는 변수에 저장되는 값이 입력한 값 그대로 저장이 된다. 예를들어 숫자나 문자 혹은 문자열 같은 경우, 변수에 저장했을 때 그 데이터가 이진수로 변환되어 변수라는 메모리 공간에 그대로 저장이 된다. 하지만 Reference 타입의 경우 해당 데이터가 그대로 변수에 저장되지 않는다. 그 데이터를 가리키는(참조하는) 주소를 저장한다. Reference 데이터 타입의 대표적인 예는 Array와 Object이다.

 

1. Primitive / Reference 값 복사

// Primitive data type 복사 특징
    var 이름1 = '김';
    var 이름2 = 이름1; // 복사
    console.log(이름2); // '김'
    이름1 = '박'
    console.log(이름1) // '박'
    console.log(이름2) // '김'

 // Reference data type 복사 특징
    var 이름1 = { name : '김' }
    var 이름2 = 이름1;
    이름1.name = '박';
    console.log(이름1.name) // '박'
    console.log(이름2.name) // '박'
  • Primitive의 경우, 값을 복사할 때 변수를 사용하면 값이 그대로 복사가 된다. 위의 경우 이름1에 저장된 '김'이라는 이름을 이름2에서도 저장하고 싶을 때 변수 이름을 할당하면 문제없이 복사가 된다.
  • Reference의 경우, 값을 복사할 때 변수를 사용하면 값이 아닌 주소가 복사가 된다. 즉, 이름1이 { name : '김' }이라는 오브젝트를 가리키는 주소 값을 담고 있으므로 이름2에 이름1을 할당하면 주소를 복사하게 된다.
    • 문제는 이름1의 name 값을 바꿨음에도 이름2의 name 값까지 같이 변경이 된다. 이유는 이름1과 이름2가 하나의 오브젝트 주소 값을 공유하고 있기 때문이다.
var 이름1 = { name : '김' }; // 김을 가리킴
var 이름2 = { name : '김' }; // 김을 가리킴

console.log(이름1 === 이름2); // false
  • 위의 경우, 이름1과 이름2가 내용이 같은 오브젝트를 담고 있다. 따라서 코드 상으로는 이름1과 이름2가 같아 보이지만 실제로는 같다고 해석되지 않는다. 이름1과 이름2의 오브젝트 값이 같더라도 두 변수는 오브젝트를 가리키는 주소가 저장되어 있다. 따라서 이 둘은 각각 다른 주소 값을 갖고 있기 때문에 두 변수가 같다고 할 수 없다. (Reference type의 특징)

2. Reference 값 변경

var 이름1 = { name : '김' };

    function 변경(obj){
        obj.name = '박';
    }

변경(이름1); // 이름1 = { name : '박' }
( = 변경(obj = 이름1)  )
  • 함수에 파라미터를 작성한다는 것은 새로운 변수를 선언한다는 뜻이다. 즉, 함수를 실행할 때 파라미터를 전달하면 함수의 파라미터(obj)가 이름1의 변수를 할당받게 되는 것이다. 즉 obj는 이름1의 오브젝트 주소 값을 가지므로 obj의 name을 변경하면 이름1의 name도 같이 변경이 된다.
    • 오브젝트의 속성을 변경하는 것은 크게 문제가 없다.
var 이름1 = { name : '김'};

    function 변경(obj){
        obj = { name : '박' };

    }

변경(이름1); // 이름1 = { name : '김' };
( = 변경(obj = 이름1) )
  • 위의 경우도 마찬가지로 변수 obj에 이름1의 주소가 할당된다. 이번에는 오브젝트의 한 속성을 바꾸는 것이 아니라 오브젝트 전체를 변경하는 함수이다. 하지만 출력 값을 보면 함수가 정상적으로 실행되지 않은 것처럼 보인다. name이 '박'으로 변경되지 않고 그대로 '김'이기 때문이다. 이름1의 오브젝트는 아예 변경이 되지 않은 것이다. 그 이유는 obj가 이름1 오브젝트의 주소값을 할당하였다가 함수를 만난 뒤에 { name : '박' }이라는 새로운 오브젝트를 할당받았기 때문이다. 그 결과 obj는 새로운 주소값을 할당하였고 obj와 이름1은 서로 다른 오브젝트를 가리키게 되었다.
    • 즉, 파라미터에 = { } , = [ ]을 해봤자 원래 오브젝트는 변경되지 않는다. ( 파라미터가 가리키는 주소만 변경 )

3. Constructor(생성자), 오브젝트를 여러개 생성하는 방법

  • 생성자를 사용하면 오브젝트를 마구 찍어내거나, 비슷한 오브젝트를 여러개 만들 수 있다.
  • 생성자는 함수를 사용하여 만들 수 있으며, 보통 대문자로 시작한다. (일반함수와 구분하기 위해서)
function Student(이름){
        this.name = 이름; // this는 새로 생성되는 object를 뜻함 (인스턴스)
        this.age = 15; // constructor를 통해 오브젝트에 새로 생성되는 속성을 만들 수 있음
        this.sayHi = function(){ // 함수도 추가 가능
            console.log('안녕하세요 ' + this.name + ' 입니다.');
        };
}

var 학생1 = new Student('손흥민'); // 오브젝트 생성하는 방법
학생1.sayHi(); // 오브젝트 내 함수 사용
  • 생성자를 통해 오브젝트를 만들 경우 각각의 오브젝트에 다른 값을 저장해야 할 때 파라미터를 전달할 수 있다.
    • this를 사용하면 오브젝트의 속성에 접근할 수 있으며 전달받은 파라미터를 할당할 수 있다.
    • this는 생성자로 인해 새로 생성되는 object를 뜻하며, 이를 Instance(인스턴스)라고 한다.
  • 생성자를 사용하여 오브젝트를 만든다면,
    1. 하드코딩하지 않고 유연하게 오브젝트를 생성할 수 있다.
    2. 반복문을 사용하여 여러 개를 생성할 수 있다.
function 상품(name, price){
        this.name = name;
        this.price = price;
        this.부가세 = function(){
            console.log(this.price * 0.1);
        }
    }

var product1 = new 상품('shirts',50000); // 상품{name : 'shirts', price: 50000, 부가세 : f}
var product2 = new 상품('pants',60000); // 상품{name : 'pants', price: 60000, 부가세 : f}
  • product1과 product2를 콘솔창에 입력하면 위와 같이 나온다. 보통 X{ key : value, key : f } 형태이다.
    • X에 해당하는 부분, 위 코드 대로라면 '상품'은 생성자의 이름을 뜻한다. 위의 경우엔 생성자의 이름을 상품이라고 하였다.
    • 생성자의 key - value 가 오브젝트 형태로 출력되며 함수의 경우 f 로 표시된다.

 

자료 출처 : https://codingapple.com