2010-07-27 4 views
4

그래서 나는 전체 개발 객체 지향 JavaScript 실습을 조사해 왔으며 다음 예제에 대해 궁금해합니다. 내가 알고있는 것처럼JavaScript 캡슐화

, 다음의 '비밀'필드 '개인'이다 (그리고 그것은 나에게 의미가 있습니다) :

var MyObject = function() { 

    var secret = 'sshhh'; 

    this.getSecret() = function() { 
     return secret; 
    } 

} 

를이는 필드 비밀은 함수 영역 내부 기능이 있기 때문에 액세스 할 수 있지만 밖에서 아무것도 ... 지금까지는 너무 좋아.

그러나 나는 (더글러스 크록 포드의 책에서 특히) 주위 다음 본 적이 :

var MyObject = function() { 

    var secret = 'sshhh'; 

    return { 
     getSecret : function() { 
      return secret; 
     } 
    } 

}(); 

과의 차이가 무엇인지 궁금 해서요, 왜 더 나은 무엇입니까? 이 경우 우리는 개인 필드가있는 것과 동일한 객체를 반환하지는 않지만 필드에 직접 액세스 할 수 없으므로 큰 이점을 얻지 못한다는 것을 알고 있습니다.

+0

내가 생각할 수있는 유일한 방법은 삭제 및 덮어 쓰기/덮어 쓰기 시나리오를 피하는 것입니다. – lucas1000001

+0

JavaScript : 좋은 부품 - 글쎄, 몇 페이지 뒤집어서 여러 번 혼란스러워하기 때문에이 책을 읽기가 거의 시작되지 않는다 ... –

+0

그래, 말해봐 : S - 좋다. 마음! – lucas1000001

답변

7

이러한 예제는 매우 다릅니다 ... 첫 번째는 new을 사용하여 생성자로 호출 될 때 "getSecret"function을 속성으로 갖는 "MyObject"function을 만듭니다. 두 번째는 "getSecret"이 function 인 "MyObject"Object을 속성으로 만듭니다.

이와 관련하여 이것은 정적 메서드와 공용 메서드의 차이점과 비슷합니다. 첫 번째 경우에는 메서드가 생성자 자체가 아니라 생성자가 호출 될 때만 존재합니다. 두 번째 경우에는 생성자가 없습니다.

그럼 당신이 가정 해 봅시다 :

var MyObject1 = function() { 
    var secret = 'sshhh'; 
    this.getSecret = function() { 
    return secret; 
    } 
} 

// ... 

var MyObject2 = function() { 
    var secret = 'sshhh'; 
    return { 
    getSecret : function() { 
     return secret; 
    } 
    } 
}(); 

을 몇 가지 테스트를 실행 :

MyObject1.getSecret(); 
// TypeError: Object has no method 'getSecret' 
var m1 = new MyObject1(); 
m1.getSecret(); 
// "sshhh" 

MyObject2.getSecret(); 
// "sshhh" 
var m2 = new MyObject2(); 
// TypeError: object is not a function 

그래서 MyObject1 클래스 같고, MyObject2는 정적 클래스와 같다.

+1

첫 번째 '클래스'(그것이 당신이 그것을 부를 수있는 것이라면)의 그것이 사실이라고 나는 생각하지 않는다. 내가 알기로, 당신이'new MyObject()'를 부를 때, 'this'프라퍼티는 전역 스코프 (함수 호출에서와 같이)에서 여러분이 생성하고있는 객체로 변경된다. 그럼 this.getSecret은 전역 범위가 아닌 객체에 연결됩니다. (누군가가이 모든 것을 잘못 쓰면 주저하지 마십시오.) – lucas1000001

+0

잠깐만, 편집 중이지만 전화 통화 중입니다.) –

+0

Whoa 죄송합니다. 그 의견은 완전히 바뀌 었습니다 (전 세계적 범위에 대해 언급 한 것 같습니다). – lucas1000001

1

큰 개체의 경우 반환되는 개체에 명시 적으로 표시되는 항목을 표시하면 this.something을 놓친 것에 대한 걱정 대신 한 곳에서 무엇이 노출되는지 확인할 수 있습니다.

+0

근본적으로 말하자면, 그것은 단지 생성자와 최종 생성 된 객체의 분리라고 말하는 것입니까? 어떤 종류의 정보 숨기기 또는 무엇인가와 반대로 모든 다른 것보다 명확성을 위해. – lucas1000001

+0

아닙니다. 제 설명이 훌륭하지 않다는 것을 알고 있습니다. 두 가지 방법 모두 내부 정보를 숨기지 만, 후자는 더 명확하게 노출되는 정보를 보여줍니다. 두 번째 경우에는 함수가 생성자가 아니기 때문에 숨겨진 변수에 대한 범위 만 제공합니다. – andrewmu

1

더 나쁘지도 않습니다. 두 가지 시나리오에서 사용됩니다.

당신은 '클래스'로 기능을 사용하기 위해 잘 작동주는 첫 번째 예 :

두 번째 예제가/"싱글"그것에 몇 가지 기능을 인라인 개체를 정의하는 잘 작동
stuff = new MyObject(); 

. 당신이 그것을에 좀 더 정보가 계시 모듈 패턴으로 참조 문서가 원하는 경우

0

그들은 기능적으로 것 같은, 적어도 그것은 호출에 관해서 new MyObject().getSecret();. 유일한 차이점은 본질적으로 "팩토리 메서드"이며 개체를 만들기 때문에 후자를 new과 함께 호출 할 필요가 없다는 것입니다.

+1

* 기능적으로 * 동일합니까? 'MyObject(). getSecret()'과'MyObject.getSecret()'은 나에게 똑같은 것처럼 보이지 않습니다 ... – gnarf

+0

아마 "기능적으로"라는 단어에 대해 혼란 스러울 것입니다. 에서와 같이 둘 다 새 객체를 만들고 비밀 속성을 반환하는 것과 똑같은 기능을 수행합니다. 구문은 "함수"의 일부가 아닙니다. –

0

내가 말할 수있는 것은 첫 번째 예제는 구현하기가 더 간단하다는 것입니다.첫 번째 변수는 MyObject()이라는 간단한 문자열을 반환하는 함수입니다.

두 번째는 MyObject.getSecret()과 함께 "secret"을 반환하는 객체를 반환합니다.

그래서 나는 이전 예제 (정확히 똑같은 일을하기 위해 적은 코드가 필요함)를 호출하여 함수에서 "비밀"을 얻습니다.

아마도 두 번째 예제를 사용했을 때 Crockford는 더 큰 아이디어를 가지고있었습니다.

0

Javascript를 사용하면 Douglas Crockford가 설명한 것처럼 "객체는 이름 - 값 쌍의 모음입니다."따라서 우리는 언제든지 원하는 모든 객체에 대한 속성을 동적으로 정의 할 수 있습니다. * 어떤 예방 /; 기능 사람 (이름, SSN) { this.name = 이름;

VAR 사람 = (함수() { var에 SSN = "":이 자바 스크립트에 캡슐화를 달성하기 위해 하나의 생각이다 SSN을 등록 */ Object.defineProperty의 변경 (이 'SSN'{ 값 ","쓰기 : 거짓 열거 : 사실, 구성 : FALSE }) this.getSSN = 함수 () { return SSN; }; this.setSSN = function (ssn) { console.log ("여기에 빨간 테이프 확인"); SSN = ssn; }; this.setSSN (SSN); } return person; }})();

개체가 인스턴스화되면 IEF (즉시 실행 된 함수)를 실행하고 외부 함수 (즉, 클로저)의 변수 SSN에 대한 특수 참조를 보유하는 내부 "Person"함수를 반환합니다.이 변수는 반환되는 객체 내의 public 메소드를 통해서만 액세스 할 수 있으므로 Java 클래스에서 동작을 시뮬레이트합니다.

var p = new Person("Marcelo","444"); 
var p2 = new Person("Joe","777"); 
p 
Person {name: "Marcelo", SSN: "", getSSN: function, setSSN: function} 
p2 
Person {name: "Joe", SSN: "", getSSN: function, setSSN: function} 
p.setSSN("111") 
p2.setSSN("222") 
p.getSSN() 
"111" 
p2.getSSN() 
"222" 
p.SSN = "999" 
p.SSN 
""