티스토리 뷰

2) 객체 리터럴과 this

자바스크립트의 객체는 딕셔너리, 키와 밸류의 어떤 해시 맵 구조의 형태입니다. 키와 밸류로 된 어떤 값을 할당해놔서 그걸 통하여 외부에서 쓸 수가 있는 것입니다.

 

자바스크립트 객체의 활용

  • 자바스크립트 객체는 사실 객체리터럴이라고 얘기합니다.
    (리터럴이란소스 코드의 고정된 값을 대표하는 용어이며변수 초기화에 종종 사용된다객체를 표현할 수 있으며 함수 리터럴 방식을 이용한 객체 리터럴에서는 이 객체의 메소드도 리터럴이 될 수 있다자바스크립트는 리터럴 표기법을 이용해필요한 요소들을 열거하는 것 만으로 객체를 만들 수 있다.
    출처https://ko.wikipedia.org/wiki/%EB%A6%AC%ED%84%B0%EB%9F%B4)
  • 자바스크립트에서는 객체 리터럴이라는 표현식을 이용해 객체를 쉽게 만들 수 있습니다.
    한 가지 비슷한 예제를 하나 살펴보겠습니다.

var healthObj = {

  name : "달리기",

  lastTime : "PM10:12",

  showHealth : function() {

    console.log(this.name + ", 오늘은 " + this.lastTime + "에 운동을 하셨네요");

  }

}

healthObj.showHealth();  // 달리기님, 오늘은 PM10:12에 운동을 하셨네요

 

  • healthObj라는 오브젝트(healthObj 인스턴스라고도 합니다)는 하나의 객체입니다. 위의 코드가 healthObj 객체 안에 없었다면 해당 코드는 전역 변수로 선언되었을 것입니다.
  • showHealth 안의 this는 이 함수의 실행 컨텍스트, 이 함수가 참조하고 있는 객체의 참조 지점을 알려주는 것입니다. 다시 말해 해당 this가 가리키는 것은 healthObj 입니다.
  • this는 어떤 환경에서 불렸는지, 또는 실행 타이밍에 따라 결정됩니다.
  • 위 코드의 this는 healthObj를 의미하며 이 객체의 name 속성, lastTime 속성, showHealth 속성을 접근할 수 있습니다.
  • healthObj.lastTime을 직접 바꾸는 것은 좋지 않은 방법입니다. 보통 속성들은 메서드를 이용하여 바꿉니다. 아래는 직접 바꾸는 예시입니다.

healthObj.lastTime="AM 06:20";

healthObj.showHealth();   // 달리기님, 오늘은 AM 06:20에 운동을 하셨네요

 

  • 이런 형태로 있는 코드들 중 비슷한 분류의 것들을 하나의 오브젝트로 묶어두시는 게 좋습니다.

var todo = {

    todos: [],

    addTodo : function(newTodo){

        this.todos.push(newTodo);

    },

    showTodo : function(){

        return this.todos;

    }

}

todo.addTodo("play");

todo.addTodo("sleeping...");

todo.showTodo();    // ["play", "sleeping..."]

 

  • 이런 식으로 접근을 하는 게 일반적인 객체입니다. 중요한 건 키, 밸류, 메서드로 이루어져 있다는 겁니다. 객체는 이렇게 비슷한 일들,  todo의 속성을 제어하는 어떤 속성들과 관련된 것들을 묶어주시면 됩니다. 뭐든지 다 묶을 필요는 없습니다.
  • 일반적으로 자바스크립트의 객체는 싱글톤입니다. 하나의 객체를 반환하게 돼있습니다.
  • 자바스크립트로 OOP를 하려면 ES6의 클래스를 쓴다거나해서 상속을 할 수도 있는 거고 물론 또는 프로토타입에 대한 이해 그래서 이제 뉴 키워드를 써가지고 객체를 만드는, 동적으로 다이내믹 객체를 만드는 방법 등을 할 수 있습니다. 하지만 최종적으로 자바스크립트 객체 그 자체의 모습은 객체 리터럴이다라는 것을 기억하면 좋겠습니다.

 

this

  • 객체 안에서의 this는 그 객체 자신을 가리킵니다.
    참고로, ES6에서는 객체에서 메서드를 사용할 때 'function' 키워드를 생략할 수 있습니다.

const obj = {

   getName() {

     return this.name;

     },

  setName(name) {

      this.name = name;

    }

}

obj.setName("crong");

const result = obj.getName();   //"crong"

 

this 좀 더 알아보기

  • JavaScript에는 전역스크립트나 함수가 실행될 때 실행문맥(Execution context)이 생성됩니다.
    (참고로 실제 실행은 브라우저내에 stack 이라는 메모리 공간에 올라가서 실행됩니다)
  • 모든 context에는 참조하고 있는 객체(thisBinding이라 함)가 존재하는데, 현재 context가 참조하고 있는 객체를 알기 위해서는 this를 사용할 수 있습니다.
  • 다시 말해, 함수가 실행될때 함수에서 가리키는 this 키워드를 출력해보면 context가 참조하고 있는 객체를 알 수 있습니다.

function get() {

    return this;

}

 

get(); //window. 함수가 실행될때의 컨텍스트는 window를 참조한다.

new get(); //object. new키워드를 쓰면 새로운 object context가 생성된다.

 

  • 함수가 부를 때 실행 context라는 게 생기는데 해당 context가 참조하고 있는 객체가 뭔지에 따라 this가 달라집니다. 이전 코드에서 참조하고 있는 객체는 healthObj 이었습니다. 그 메서드 입장에서는 this를 사용하여 healthObj를 참조할 수 있었습니다.
  • this는 어떤 경우에는 윈도우를 가리킬 수도 있고 오브젝트에 new 키워드를 쓰면 새로운 object를 가리키기도 합니다. this는 바뀔 수가 있다는 것입니다.

var others = {

    todos: "난 아무것도 하지 않는다"

}

var todo = {

    todos: ["자바스크립트 공부하기"],

    addTodo : function(newTodo){

        this.todos.push(newTodo);

    },

    showTodo : function(){

        return this.todos;

    }

}

todo.showTodo();   //"자바스크립트 공부하기"

todo.showTodo.call(others);   //"난 아무것도 하지 않는다"

 

  • call() 함수를 사용하면 컨텍스트가 가리키는 참조점을 변경할 수 있습니다.
  • 위의 예제에서 todo의 todos는 "자바스크립트 공부하기"로 되어 있지만 call() 함수를 이용하여 showTodo() 컨텍스트가 가리키는 참조점을 변경하면 참조하는 객체가 others로 바뀌어 "난 아무것도 하지 않는다"가 반환됩니다. this는 이렇게 바뀔 수 있습니다.
  • 탭 UI를 객체로 구현할 수도 있습니다.  UI를 하나의 객체로 만들고 탭 UI의 메서드, 이벤트 등록, Ajax 호출, 템플릿 입력 등을 하나의 객체에 넣은 후 tabUI.sendAjax, this.sendAjax, 또는 tabUI.init으로 시작점을 포인트를 주어 이벤트 등록을 한다던지, 데이터를 미리 가져온다던지 등의 작업을 처리할 수 있습니다. 즉, 하나의 컴포넌트를 그러한 객체로 만들 수도 있다는 것입니다.

생각해보기

  • Tab UI와 같은 UI요소 하나를 객체리터럴로 묶을 수 있습니다.
  • 본인이 이전에 구현했던 코드를 보면서 어떻게 객체리터럴 형태로 변경할 수 있을지 고민해보세요.
  • object literal pattern 키워드를 통해서 좀 더 다양한 예제를 찾아보세요.
Comments