- Today
- Yesterday
- Total
메이쁘
[기본CS] 자바스크립트의 객체에 대해 파헤쳐보자. 본문
안녕하세요.
자바스크립트라는 언어에 대해 기본부터 다시 공부하며
자바스크립트를 정복하기 위해 포스팅하게 되었습니다.
여러 블로그 글을 참고하며 머릿속에 집어넣고, 이를 정리하는 차원에서 작성해봅니다.
자바스크립트에서 객체(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
'Language > JavaScript' 카테고리의 다른 글
[ES6] 순회에 사용하는 forEach(+ for - in / for - of), filter, map, reduce에 대해 핵심만 짧게 알아보자! (0) | 2020.08.01 |
---|---|
[jQuery] document.getElementById() 와 $() 의 차이 및 적절한 사용법 (0) | 2020.05.22 |