자바스크립트 개발을 하다가 일정 수준 이상이 되면, 코드 가독성 및 더 좋은 패턴에 대해 연구 하게 되고, 널리 쓰이는 패턴을 내 코드에 사용하곤 한다.

물론 책으로도 대부분 접할수가 있으며JSHINT 나, JSLINT와 같은 정적 검사 도구로 체크하여 잘못된 패턴을 지양하고, 좋은 패턴을 사용한다.

그 중  자바스크립트에서 가장 중요한 패턴이라고 알려진 Literal 표기법에 대해서 알아보자.

본 포스팅에서는 우선 객체 선언에서만 다룰 예정이다.

우선 자바스크립트의 DATA Type은 총 7개가 있으며 아래와 같다.

  1. Boolean
  2. Null
  3. Undefined
  4. Number
  5. String
  6. Symbol (ES6 에서 추가)
  7. Object

위 리스트에서 6번까지는 primitive type 이며  Object 는 primitive가 아니다.  여기서 각 type별로 선언하는 여러가지 방법이 있지만 Object는 다음과 같이 주로 선언한다.

var obj1 = {};
var obj2 = new Object();

위 코드에서 obj1 과 obj2는 객체는 동일한 역할을 하게 된다. 즉 아무것도 없는 빈 객체를 생성해서, 향후 프로퍼티 또는 메소드를 추가할 수 있는 객체가 된다.

하지만 위 코드에서 좋은 패턴은 어떤 패턴일까?

주로 대부분의 포스팅이며, 책, 자료에서는 아래와 같은 방식을 좋은 패턴이라고 말한다.

var obj1 = {}; //good pattern

위 코드를 바로 literal 표기법이라고 한다. 간단하게 객체를 선언할 수 있으며 아래와 같은 코드에서는 가독성 또한 좋아진다.

//객체 생성과 할당 
var obj1 = {
  a: 1,
  b: 2
};
//객체 생성한 후 할당 
var obj2 = new Object();
obj2.a = 1;
obj2.b = 2;

그렇다면 단순히 가독성을 위해서 {} 를 new Object 에 비해 권장 하는 것일까?

이제 본론으로 들어가자

이 포스팅을 작성하면서, 갖고 있던 근원적인 물음은 다음과 같다.

1. {} 과  new Object()는  동일한 객체를 생성할까?

우선 Literal 기법과 new 기법으로 생성된 객체는 동일한 객체이다. ( 의미적으로 동일하다는 말이다. 참고로 String 은 다르다. ). 즉 같다. 

[참고]

var str1 = "";
var str2 = new String();
console.log( typeof str1 ); // "string"
console.log( typeof str2 ); // "object"

위 코드에서  str1 과 str2 는 다르다. str1 은 type이 string 이지만 str2는 object 이다.

[/참고]

1번의 물음이 해결되고 나서 다시 궁금한점이 생겼다.

2. 그렇다면 {}를 권장하는 이유는 무엇인가? ( 단순히 가독성때문에?)

사실 2번에 대한 이유는 몇가지 알고있었다. (대체적으로 가독성, 속도 정도 였고,  자바스크립트에서 내장함수가 override  되는 버그(?) )

하지만 뭔가 다른 이유가 있을 것이라 생각하며 문제를 하나씩 찾아보았다.

첫번째로 가독성이다. 

Literal 기법이 대체적으로 더 짧고 직관적이며 객체를 생성하기도 더욱 용이하다. 위에서 살펴 보았듯이 생성과 할당에 더 적합하다. 또한 가장 기본적인 데이터를 선언하는데 있어서 new 표현을 덜 쓰면서, 가독성도 더 좋아진다.

두번째는 속도다. 

이미 여러가지 실험을 통해 Literal기법이 속도가 더 빠르다는것이 증명되었다.  ( 약 12.14% 빠르다 )

http://jsperf.com/new-array-vs-literal/26

하지만 사실상 미미하며, 정말 복잡도가 높은 어플리케이션을 개발할 경우만 필요할 수도 있다고 생각한다. ( 개인적 의견 ) . 이전 브라우저에서는 많이 차이가 있었지만, 최근에는 그 격차가 많이 좁혀진게 아닐까 생각한다.

* 속도가 왜 빠른지는 나중 포스팅에서 다뤄보자.. 중요하다. 

마지막으로 세벗째는 Overriden에 따른 예방이다. 

우선 자바스크립트는 기본 함수 조차도 Overriden이 된다.  overriden이란 재정의란 의미로 Object 도 어떻게 보면 자바스크립트에서 함수이기도 한다. 하지만 이 함수를 재정의 할수 있다. 예제를 한번 만들어보자

Object = function(){ 
 alert("재정의"); 
};
var obj1 = new Object(); //alert 발생

즉 Object 란  내장함수 조차도 재정의 되어서 전혀 예상치 못한 결과를 초래할 수 있다.

이렇게 literal기법으로 선언 하는것이 더욱 효과적이며 해당 근거는 위에 3가지 정도로 요약할 수 있다.

별거 아닌거지만, 가장 기본적이며, 향후에 Array, String, Number 에대해서도 다뤄볼 예정이다. ( String은 또 다르다. )

 

자바스크립트를 공부하다보면, 변수, 함수, 객체, 프로퍼티 와 같은 단어를 많이 사용하고 접하게 된다. 처음 접할때는 변수 == 프로퍼티 라고 이해를 하게 되지만, 시간이 지나고 조금더 고민하다보면 뭔가 미묘한 차이들이 있다.

그래서 누군가 이 함수에서 변수는 무엇이고 프로퍼티는 무엇이냐 ? 라고 물어보게 된다면 더욱 더 헷갈리게 된다. 그래서 이번기회를 통해 조금 정리해보았다.

예를들어 아래와 같은 코드가 있다고 하자.

var a = "test";

일반적으로 변수는 var 로 선언을 하게 된다. 여기서 a 는 해당 스코프 안의 변수 이다. 절대 해당 스코프에서 프로퍼티라고는 하지 않는다.

하지만 만약에 다음과 같이 작성한다고 하자.

this.b = "test";

this를 통해서 b를 선언하게 되면, b 는 해당 객체의 프로퍼티가 되게 된다. 단순하게 var로 선언하면 변수, this 로 선언하면 프로퍼티 라고한다.

설명을 좀더 자세히 하기 위해 전체 코드를 작성해보겠다.

var setMyName = function( value ){
  var name = value;
  this.name = value;
};
var setName = new setMyName( "kazikai" );
console.log( setName.name ); //kazikai

위 코드에서 발생하는 name 은 var name 으로 저장된 값일까? this.name 으로 저장된 값일까?

정답은 this.name 으로 저장된 값이다.  이유는 setName 이란 변수는 setMyName의 인스턴스를 통해 만들어진 객체이며, 해당 객체에서 this.name 이라고 선언된 name은 인스턴스로 만들어진 객체의 프로퍼티가 된다.

조금 더 추가 설명을 하자면,

JavaScript에서는 private public 의 개념이 따로 존재하지 않는다.

Public이 외부에서 접근 가능하고 private이 내부에서만 접근가능한 변수라고 한다면,

this 는 public 이고, var는 private 한 변수라고 할 수 있다.

아래는 더글라스 크락포트가 작성한 private 에 관한 개념. 이 개념을 이해하면, 변수와 프로퍼티의 차이점을 더욱 더 자세히 이해할 수 있다.

http://javascript.crockford.com/private.html