[ES] Object

LateMarch·2023년 1월 11일
0

JavaScript Objects

자바스크립트 객체(JavaScript Object)는 값과 mothod(function)를 갖는 여러 속성(property)을 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반환.
profile
latemarch

0개의 댓글