Private Members in JavaScript -Douglas Crockford

-- JavaScript 2011. 11. 17. 13:54
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

JavaScript 세상에서가장오해받는언어이다. 일부에선, private (속성의;역자) instance 변수와 메소드의 부재로 인해, 객체의 '정보 은닉' 기능이 결여되어 있다고 믿기도 한다. 그러나 이것은 오해다. JavaScript 객체는 private 멤버를 가질 수 있다. 여기 해답이 있다.


Objects

JavaScript
는 근본적으로 거의 object 이다. Array type object 이고, Function type object 이며, Object type object 이다. 그럼 여기서 말하는 object 란 무엇인가? object name-value 쌍의 집합이다. name string 이고, value string, number, boolean, 그리고 (array function 을 포함한) object 이다. 마치 hashtable 처럼 구현되기 때문에 아주 빠르게 value 에 접근할 수 있다.

만약 value function 이라면, 이것을 method 라고 볼 수 있다. object 의 한 메소드가 호출되면, 'this' 변수는 해당 object 가 되고이 메소드는 'this' 변수를 통해 instance 변수에 접근하게 된다
.

object
'생성자'라는 함수에 의해 생성된다. 이 함수는 object 를 초기화한다. '생성자'에서, 여타의 언어에서 제공되는 class 의 속성들-static 변수와 메소드를 포함한- 이 제공된다
.


Public

object
의 멤버는 모두 public 멤버이다. 어떤 function 이든 이 멤버에 접근해서 수정하거나 지우거나 또는 새로운 멤버를 추가할 수 있다. 여기, 새로운 object 에 멤버를 추가하는 2가지 대표적인 방법이 있다.

In the constructor

이 기법은 보통 public (속성의;역자) instance 변수를 초기화하는데 사용된다. '생성자'에서 사용된 'this' 변수는 새로운 멤버를 추가하는데 사용된다.

function Container(param) {
    this.member = param;
}


다음과 같이 새로운 object 를 생성하면,

var myContainer = new Container('abc');

myContainer.member 'abc'라는 값을 갖는다.

In the prototype

이 기법은 보통 public 메소드를 추가하는데 사용된다. 사용된 멤버 변수가 객체내에 이미 존재하던 것이 아니면, 객체의 생성자의 prototype 멤버로부터 찾아오게 된다. prototype 메커니즘은 상속 구현에 사용되며 또한, prototype 을 사용하면 메모리 사용도 줄일 수 있다. 하나의 '생성자'로부터 생성된 모든 object 에 하나의 메소드를 추가하고자 한다면, function '생성자' prototype 에 추가하면 된다.

Container.prototype.stamp = function(string) {
return this.member + string; 
};


이제 다음과 같이 해당 메소드를 호출할 수 있게 되었고,

myContainer.stamp('def');

이는 결과적으로 'abcdef' 라는 값을 산출한다.


Private

private
멤버는 생성자에서 만들 수 있다. 일반적으로 var 로 선언한 변수와 함수의 매개변수는 private 멤버이다.

function Container(param) {
    this.member = param;
    var secret = 3;
    var that = this;
}



이 생성자는 param, secret, that 이라는 3개의 private instance 변수를 생성한다. object의 멤버로 생성되었지만, 이 변수들은 외부에서도, public 메소드에서도 접근할 수 없다. 이것들은 private 메소드에서 접근 가능한데, private 메소드는 생성자 내부에서의 function 정의로 구현된다.

function Container(param) {
    function dec() {
        if (secret > 0) {
            secret += -1;
            return true;
        } else {
            return false;
        }
    }

    this.member = param;
    var secret = 3;
    var that = this;
}



private
메소드인 dec instance 변수인 secret 을 검사해서, 0 보다 크면, 1 감소시키고 true 를 리턴한다. 그렇지 않다면, false 를 리턴한다. 이로인해 이 object 의 사용을  3회로 제한할 수 있게 되었다.

규정대로라면, 우리는 private 속성의 that 변수를 만들어서, object  private 메소드에서 가용하게 할 수 있는데, 이는 ECMAScript 스펙에 의해 inner fuction 에서 this 가 잘못 세팅되는 경우에 대한 차선책이다
.

private
메소드는 public 메소드에서 호출될 수 없다. 보다 쓸만한 private 메소드 구현을 위해 이제 privileged 메소드를 알아봐야겠다
.


Privileged

privileged
메소드는 private 변수와 메소드에 접근할 수 있으며, 또한, public 메소드와 외부에서 이 메소드를 사용할 수 있다. privileged 메소드를 삭제하거나 대체할 수 있는 반면, 수정하거나 secret 을 공개하게 할 수는 없다.

function Container(param) {
    function dec() {
        if (secret > 0) {
            secret += -1;
            return true;
        } else {
            return false;
        }
    }

    this.member = param;
    var secret = 3;
    var that = this;

    this.service = function() {
        if (dec()) {
            return that.member;
        } else {
            return null;
        }
    };
}



service
privileged 메소드이다. myContainer.service()를 호출하면 처음 3번은 'abc'를 리턴하고, 그후에는 null 을 리턴한다. service private dec 메소드를 호출하고 dec private 변수인 secret 에 접근한다. service 는 타 object 와 메소드에서 사용할 수 있지만, private 멤버에의 직접적인 접근은 허용하지 않는다.


Closures

JavaScript
에서 이러한 public, private, privileged 멤버들의 구현이 가능한 것은, closure 때문이다. closure 의 의미는(Javas-ript closure 구현이 시사하는 바는), inner function outer function  var 선언 변수와 매개변수에 접근할 수 있으며, 심지어 outer function 이 리턴된 이후에도 가능하다는 뜻이다. 이는 굉장히 강력한 언어 속성인데, JavaScript 에서 어떻게 이것이 가능한지 파헤쳐놓은 책은 아직은 없다. 대부분 아예 언급할 생각조차 없는 것 같다.

private
privileged 멤버는 object 가 생성될 때에만 만들 수 있다. 반면, public 멤버는 언제든 만들 수 있다
.


Patterns

Public

function Constructor(...) {
    this.membername = value;
}
Constructor.prototype.membername = value;



Private

function Constructor(...) {
    var that = this;
    var membername = value;

    function membername(...) {...}
}



Note: function
구문

function membername(...) {...}


var membername = function(...) {...};

표현의 축약이다.


Privileged

function Constructor(...) {
    this.membername = function (...) {...};
}


출처 : http://mulriver.egloos.com/4666528

'-- JavaScript' 카테고리의 다른 글

Javascript URLEncode 비교  (0) 2011.12.02
javascript ajax 구현  (0) 2011.12.01
javascript으로 trim, ltrim, rtirm 구현  (0) 2011.11.30
Javascript Closure  (0) 2011.11.17
자바스크립트에서의 함수포인터  (0) 2007.08.09
posted by 어린왕자악꿍