메이쁘

[기본CS] 자바스크립트의 객체에 대해 파헤쳐보자. 본문

Language/JavaScript

[기본CS] 자바스크립트의 객체에 대해 파헤쳐보자.

메이쁘 2020. 8. 18. 23:29

안녕하세요.

 

자바스크립트라는 언어에 대해 기본부터 다시 공부하며

 

자바스크립트를 정복하기 위해 포스팅하게 되었습니다.

 

여러 블로그 글을 참고하며 머릿속에 집어넣고, 이를 정리하는 차원에서 작성해봅니다.

 

 

 

 

 

 

자바스크립트에서 객체(Object) 란?


  -  키(Key) 와 값(Value) 로 이루어진 프로퍼티(property) 들의 집합.

 

  -  즉, 여러 프로퍼티(Key - value) 들을 하나의 변수(Object 변수명) 안에 담을 수 있는 데이터 타입입니다.

 

  -  이러한 프로퍼티의 값(value) 으로 자바스크립트의 모든 데이터가 가능하다는 자바스크립트만의 특징이 있습니다. 그래서 객체 내 값으로 객체, 배열, 정규표현식, 함수 등을 사용할 수 있습니다.

  *** 자바스크립트의 함수는 일급 객체로서, 하나의 값으로 취급할 수 있습니다.

 

  -  다른 의미로, 객체는 데이터를 의미하는 프로퍼티와 이러한 데이터를 조작하고 참조할 수 있는 동작을 뜻하는 메소드로 구성된 집합입니다. 그렇기 때문에, 객체는 데이터와 동작을 하나의 단위로 묶을 수 있어(구조화) 유용합니다.

  *** ex. 객체 안에 변수 선언, 변수에 대한 조작 함수 가 들어갈 수 있습니다!

  *** 프로퍼티의 값이 함수인 경우, 외부 함수와 구분짓기 위해 메소드라고 합니다. 즉, 메소드는 객체 내부에 값으로 정의된 함수를 뜻합니다.

 

  -  객체지향의 상속을 위해 프로토타입(prototype) 이라고 하는 객체의 프로퍼티와 메소드를 상속받을 수 있습니다.

 

  -  이미 존재하는 프로퍼티의 키를 중복해서 선언하게되면, 나중에 선언한 키와 값으로 덮어씌워집니다.

 

  -  배열과는 다르게 객체는 프로퍼티의 순서를 보장하지 않습니다.

 

  -  객체 변수를 복사하면 객체 변수의 참조 값만 복사되고 객체 자체가 복사되지 않습니다. (얕은 복사)

 

 

객체 생성 방법


  -  객체 생성 방법은 크게 두 가지가 있습니다.

 

  -  Object literal(객체 리터럴), Object constructor(객체 생성자) 가 있습니다.

 

객체 리터럴 방식

 

  -  가장 이상적인 객체 생성 방법입니다.

 

  -  {} (중괄호) 를 이용해서 생성하는데, 중괄호가 비어있으면 빈 객체를, 중괄호 내 프로퍼티가 들어가면 프로퍼티가 추가된 객체를 생성합니다.

 
var obj = {};
console.log(typeof obj);  // object

var obj = {
    name : "Maivve",
    type : "tistory",
    menu : "JavaScript",
    greet : function main() {
        console.log("hi! my name is " + this.name + ", and my blog is " + this.type);
    }
};

console.log(typeof obj);  // object
console.log(obj.greet());  // hi! my name is Maivve, and my blog is tistory

  -  객체 리터럴 생성

 

 

객체 생성자 방식

  -  new 연산자와 Object 생성자 함수를 호출하여 생성하는 방법입니다.

   

  -  여기서 생성자 함수란, 객체 생성과 동시에 초기화하는 함수를 말합니다.

 

  -  또한, 인스턴스(instance) 란 생성자 함수를 통해 생성된 객체를 뜻합니다.

 

*** 객체와 인스턴스 차이

ex.

객체         

  ->  Person person; // person 이라고 선언만 되어있는 Person 껍데기.

인스턴스

  ->  Person person = new Person(); // person 객체에 Person의 생성자 함수를 통해 생성된 객체

 

  -  주로 객체 생성 시에는 객체 리터럴 방식이 사용됩니다.

 

  -  자바스크립트에서는 이러한 Object 만 생성자 함수를 갖고 있는 것이 아니라, String, Number, Boolean, Array, Date, RegExp 등에도 생성자 함수를 가지고 있습니다. (빌트인 생성자 함수. 곧 알려드릴게요!)

 

var obj = new Object();
console.log(typeof obj);  // object

// 객체 내 프로퍼티 추가
obj.name = "Maivve";
obj.type = "tistory";
obj.menu = "JavaScript";
obj.greet = function() {
  console.log("내 이름은 " + this.name + " 이야.");
};

console.log(obj.menu);  // JavaScript
console.log(obj.greet());  // 내 이름은 Maivve 이야.

  -  객체 생성자 생성

  

  -  객체 리터럴 이든, 객체 생성자 든 간에 프로퍼티 추가 방식은 동일합니다.

 

 

그렇다고 한다면.

 

만약에 위 객체에서 type와 menu는 동일하지만, name 값만 다른 객체를 여러 개 만들어내고자 한다면 만들 때마다 프로퍼티 하나하나 추가해야 할까요?

 

그러면 매우 번거롭고 복잡하겠죠..

 

자바 클래스의 생성자 함수와는 비슷하지만 구조와 방식이 다른 함수형 생성자를 사용하여 위 문제점을 해결할 수 있습니다!!

 

 

 

생성자 함수


  -  생성자의 특징을 가지는 function(함수) 입니다.

  

  -  다른 함수들과 차이점을 두기 위해 함수명의 첫 글자를 대문자로 작성합니다.

 

  -  this를 사용(바인딩)하는 프로퍼티와 메소드 는 public 특성을 가지지만, 일반 프로퍼티 또는 일반 변수는 private 특성을 가집니다.

 

  -  즉, this를 사용한 프로퍼티는 외부에서 접근 가능하지만, 그 외의 일반 프로퍼티는 외부에서 접근할 수 없습니다. (대신 내부에서는 자유롭게 접근할 수 있습니다.)

 

  -  이렇게 선언한 함수에 new 연산자를 추가하여 객체를 생성합니다.

 

 

function Obj(name, menu) { // name, menu parameter 에 따라 name, menu 값이 달라짐.
  var isPrivate = true;  // 일반 변수 선언 = private
  this.name = name;  // this 선언 = public
  this.type = "tistory";  // this 선언 = public
  this.menu = menu;  // this 선언 = public
  this.greet = function() {  // this 선언 = public
    console.log("내 이름 : " + this.name);
  }
};

var obj = new Obj('Naivve', 'JavaScript'); // 객체 생성

console.log(typeof obj);  // object
console.log(obj.name);  // Naivve
console.log(obj.menu);  // JavaScript
console.log(obj.isPrivate);  // undefined (private라 참조 불가능해서)
console.log(obj.greet());  // 내 이름 : Naivve

  -  this 프로퍼티와는 다르게 일반 프로퍼티는 외부에서 접근할 수 없습니다.

 

 

그 외 객체 프로퍼티 특징


긴 설명 없이 샘플 코드를 보시면 됩니다.

 

var obj = {  // 객체 생성
  name : "Maivve",
  'blog-menu' : "JavaScript",
  10 : "ten"
};


console.log(obj.name);  // Maivve
console.log(obj[name]);  // undefined
console.log(obj['name']);  // Maivve

console.log(obj.blog-menu);  // error
console.log(obj[blog-menu]);  // error(ReferenceError : blog is not defined)
console.log(obj['blog-menu']);  // JavaScript

console.log(obj.10);  // error(SyntaxError)
console.log(obj[10]);  // ten (10 -> '10' 으로 인식함)
console.log(obj['10']);  // ten


// 객체의 프로퍼티 삭제
delete obj.name;
console.log(obj.name);  // undefined

 

 

Pass-by-Reference

  -  원시 타입의 특성인 immutable(불변성) 과는 다르게, 객체는 프로퍼티를 수시로 생성/수정/삭제 하기 때문에 mutable(가변성) 의 특징을 가지고 있습니다.

 

  -  이에 따라, 객체는 참조 타입으로 불리는데요. 참조 타입이란 원시 타입과는 다르게 해당 값의 참조 값으로 처리하는 타입을 뜻합니다.

 

  -  객체는 메모리를 어느정도 확보할지 정해지지 않아(동적 할당) 런타임(변수 할당 시점)에 메모리 공간을 어느정도 확보해두고, 메모리의 힙(Heap) 영역에 저장합니다.

 

 
var one = { val : 100 };

var two = one;
console.log(one.val + " , " + two.val);  // 100 100
console.log(one === two);  // true

two.val = 200;
console.log(one.val + " , " + two.val);  // 200 200
console.log(one === two);  // true

  -  위에서 말했듯이, 객체 복사 시 얕은 복사 방식(동일한 프로퍼티를 참조) 으로 복사됩니다.

 

  -  그렇기 때문에 복사한 객체의 프로퍼티 값을 변경하면 기존 객체의 프로퍼티 값도 바뀌게 되는 것이죠.

 

 

Pass-by-value

  -  원시 타입은 immutable(불변성) 의 특징을 갖고 있어 참조 값이 아닌 본연의 값을 복사 / 전달합니다.

 

  -  Pass-by-Reference 와는 다르게 런타임(변수 할당 시점)에 메모리의 스택(Stack) 영역고정된 메모리 공간을 차지합니다.

 

 

var one = 1;
var two = 2;

console.log(one + " , " + two);  // 1 , 2
console.log(one === two);  // false

two = one;
console.log(one + " , " + two);  // 1 , 1
console.log(one === two);  // true

two = 10;
console.log(one + " , " + two);  // 1, 10
console.log(one === two);  // false

 

 

 

 

이상 객체의 기본적인 개념과 원리, 특성에 대해 공부했습니다.

 

다음 포스팅을 기대해주세요.

 

 

틀린 부분, 오타 있으면 댓글 부탁드리겠습니다.

 

감사합니다.

 

 

 

 

참고

https://poiemaweb.com/js-object
Comments