Object
August 3, 2023
ES
JavaScript Objects
자바스크립트 객체(JavaScript Object)는 값과 mothod(function)를 갖는 여러 속성(<a href="https://developer.mozilla.org/en-US/docs/Glossary/property/JavaScript" target ="_blank">property</a>)을 hold하는 독립형 container다. 원시형을 제외하면 자바스크립트의 모든 자료형은 객체가 된다. 자바스크립트 객체는 다른 언어의 Hash
, Map
이나 Dictionary
와 비슷하나, 오브젝트 생성자로 선언되어야한다. Prototype을 보면 객체가 어떤 의미인지 아는데 더 도움이 된다.
Prototype Object
위에서 객체는 객체 생성자로 선언되어야 한다고 했다. 다음과 같이 객체를 선언 했다고 해보자.
const myObject = { city: "Madrid", greet() { console.log(`Greetings from ${this.city}`); }, }; myObject.greet(); // Greetings from Madrid
사용자가 선언한 객체의 속성은 city
와 greet()
뿐이다. 하지만 myobject.
와같이 콘솔에 호출하면 많은 속성들을 얻을 수 있다.
__defineGetter__
__defineSetter__
__lookupGetter__
__lookupSetter__
__proto__
city
constructor
greet
hasOwnProperty
isPrototypeOf
propertyIsEnumerable
toLocaleString
toString
valueOf
사용자가 선언한 city
와 greet
외에 많은 속성들이 추가 됐음을 알 수 있다. 이런 속성들은 객체가 선언됨과 동시에 prototype object
로부터 속성들을 상속받는다. 따라서 prototype object
는 자바스크립트가 제공하는 객체라면 마땅히 가져야할 속성들의 모음이라고 생각할 수 있다. 사용자가 객체를 이용하기 용이하도록 사용자가 객체를 선언할때 선언된 객체에 추가 속성을 입혀주는 것이다. 이는 Date
객체를 살펴보면서 더 명확히 알 수 있다.
Accociative Arrays
자바스크립트에서 아래 두 표현은 같은 값을 나타낸다
obj.property obj["property"]
위 표현방시의 오른쪽(property)는 식별자(identifier)로, datatype이 아니여서 프로그램에 의해 다뤄질(manipulated)수 없으므로 변수가 들어갈 수 없다. 반면 아래의 표현에서는 []
안의 값은 문자열로 자바스크립트의 datatype이고 프로그램이 다룰 수 있어서 런타임에서 만들어질 수 있다. 이와같은 특징은 객체의 값에 접근하는데 유연함을 제공하는데 이는 자바 스크립트의 객체가 연관 배열(Accociative Arrays)이기에 가능한 특성이다.
Prototype Chain
const myDate = new Date(); let object = myDate; do { object = Object.getPrototypeOf(object); console.log(object); } while (object); // Date.prototype // Object { } // null
다음과 같이 myDate
객체를 선언했다. 위에서 본바와 마찬가지로 자바스크립트는 사용자가 Date
객체를 선언할 때 객체를 사용하기 용이하게 Date
객체에 필요한 속성들을 Date.prototype
으로부터 가져온다. 그런데 특이한 점은 Date.prototype
또한 object.prototype
을 통해 기본 속성들을 상송받는다는 점이다. 생각해보면 중복되는 속성을 Date.prototype
와 object.prototype
에 따로 정의하기보다는 순차적으로 재상속하는 편이 더 효과적일 것이다. 이는 아래와 같이 표현할 수 있다.
위 그림과 같이 Date.prototype
은 object.prototype
으로 부터 필요한 속성들을 상속받고 Date
객체는 Date.prototype
으로부터 필요한 속성들을 재상속받는다. 이런 일련의 과정을 prototype chain이라고 한다.
메서드
객체 프로퍼티에 할당된 함수를 메서드라고 한다.
let user = { name: "John", age: 30 }; user.sayHi = function() { alert("안녕하세요!"); }; user.sayHi(); // 안녕하세요!
위 코드에서 sayHi
가 메서드가 된다. 메서드는 이미 정의된 함수를 이용해서 만들 수도 있다.
let user = { // ... }; // 함수 선언 function sayHi() { alert("안녕하세요!"); }; // 선언된 함수를 메서드로 등록 user.sayHi = sayHi; user.sayHi(); // 안녕하세요!
This
메서드 내부에서 this
키워드를 사용하면 객체에 접근할 수 있으며 이 때 this
는 메서드를 호출할 때 사용된 객체를 나타낸다.
let user = { name: "John", age: 30, sayHi() { // 'this'는 '현재 객체'를 나타냅니다. alert(this.name); } }; user.sayHi(); // John
객체 없는 일반 함수에서도 this
를 사용할 수 있는데, 이 경우 this
엔 undefined
가 할당된다.
자바스크립트의 this
가 다른 언어의 this
와 구별되는 점은 자바스크립트의 this
는 자유롭다는 점이다. 다른 언어의 this
는 메서드가 정의된 객체를 참조한다. 하지만 자바스크립트의 this
는 런타임에 의해 결정되어 한 함수를 여러 객체에서 각각의 메서드로 사용할 수 있는 장점이 있다.
화살표 함수는 일반 함숭롸는 달리 this
를 가지지 못한다. 화살표 함수에서 this
를 참조하면 외부 함수에서 this
를 가지고 온다.
let user = { firstName: "보라", sayHi() { let arrow = () => alert(this.firstName); arrow(); } }; user.sayHi(); // 보라
new
유사한 객체를 여러개 만들어야 할때, new
연산자를 이용한다.
function User(name) { this.name = name; this.isAdmin = false; } let user = new User("보라"); alert(user.name); // 보라 alert(user.isAdmin); // false
new User(...)
를 써서 함수를 실행하면 아래와 같은 알고리즘이 동작한다. 이 때, new
뒤에 들어가는 함수는 아무 함수나 가능하다.
- 빈 객체를 만들어
this
에 할당. - 함수 본문을 실행하고
this
에 새로운 프로퍼티를 추가해this
수정. this
반환.