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

사용자가 선언한 객체의 속성은 citygreet()뿐이다. 하지만 myobject.와같이 콘솔에 호출하면 많은 속성들을 얻을 수 있다.

__defineGetter__
__defineSetter__
__lookupGetter__
__lookupSetter__
__proto__
city
constructor
greet
hasOwnProperty
isPrototypeOf
propertyIsEnumerable
toLocaleString
toString
valueOf

사용자가 선언한 citygreet외에 많은 속성들이 추가 됐음을 알 수 있다. 이런 속성들은 객체가 선언됨과 동시에 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.prototypeobject.prototype에 따로 정의하기보다는 순차적으로 재상속하는 편이 더 효과적일 것이다. 이는 아래와 같이 표현할 수 있다.

위 그림과 같이 Date.prototypeobject.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를 사용할 수 있는데, 이 경우 thisundefined가 할당된다.

자바스크립트의 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뒤에 들어가는 함수는 아무 함수나 가능하다.

  1. 빈 객체를 만들어 this에 할당.
  2. 함수 본문을 실행하고 this에 새로운 프로퍼티를 추가해 this수정.
  3. this반환.