[javascript] 이 JavaScript 패턴은 무엇이며 왜 사용됩니까?

THREE.js를 공부하고 있는데 함수가 다음과 같이 정의되는 패턴을 발견했습니다.

var foo = ( function () {
    var bar = new Bar();

    return function ( ) {
        //actual logic using bar from above.
        //return result;
    };
}());

(예제는 여기에서 raycast 방법을 참조 하십시오 ).

이러한 방법 의 일반적인 변형은 다음과 같습니다.

var foo = function () {
    var bar = new Bar();

    //actual logic.
    //return result;
};

첫 번째 버전을 일반 변형과 비교하면 첫 번째 버전은 다음 과 같은 점이 다릅니다.

  1. 자체 실행 기능의 결과를 할당합니다.
  2. 이 함수 내에서 지역 변수를 정의합니다.
  3. 로컬 변수를 사용하는 논리가 포함 된 실제 함수를 반환합니다 .

따라서 주요 차이점은 첫 번째 변형에서 막대는 초기화시 한 번만 할당되고 두 번째 변형은 호출 될 때마다이 임시 변수를 생성한다는 것입니다.

이것이 사용되는 이유에 대한 나의 가장 좋은 추측은 bar의 인스턴스 수를 제한하고 (하나만 있음) 메모리 관리 오버 헤드를 절약한다는 것입니다.

내 질문 :

  1. 이 가정이 맞습니까?
  2. 이 패턴의 이름이 있습니까?
  3. 이것이 왜 사용됩니까?


답변

귀하의 가정은 거의 정확합니다. 먼저 검토해 봅시다.

  1. 자체 실행 기능의 반환을 할당합니다.

이를 즉시 호출 함수 표현식 또는 IIFE라고합니다.

  1. 이 함수 내에서 지역 변수를 정의합니다.

이것은 private키워드 나 기능을 제공하지 않기 때문에 JavaScript에서 개인 개체 필드를 갖는 방법입니다 .

  1. 로컬 변수를 사용하는 논리가 포함 된 실제 함수를 반환합니다.

다시 말하지만, 요점은이 지역 변수가 private이라는 것 입니다.

이 패턴의 이름이 있습니까?

AFAIK이 패턴을 Module Pattern 이라고 부를 수 있습니다 . 인용 :

모듈 패턴은 클로저를 사용하여 “개인 정보 보호”, 상태 및 조직을 캡슐화합니다. 퍼블릭 및 프라이빗 메서드와 변수의 혼합을 래핑하는 방법을 제공하여 조각이 전역 범위로 누출되고 실수로 다른 개발자의 인터페이스와 충돌하는 것을 방지합니다. 이 패턴을 사용하면 공개 API 만 반환되고 클로저 내의 다른 모든 것은 비공개로 유지됩니다.

이 두 가지 예를 비교하면 첫 번째 예가 사용되는 이유에 대한 가장 좋은 추측은 다음과 같습니다.

  1. Singleton 디자인 패턴을 구현하고 있습니다.
  2. 첫 번째 예제를 사용하여 특정 유형의 개체를 만드는 방법을 제어 할 수 있습니다. 이 점과 밀접하게 일치하는 하나 는 Effective Java에 설명 된 정적 팩토리 메소드 일 수 있습니다 .
  3. 그것은의 효율적인 같은 객체 상태마다 시간이 필요합니다.

그러나 매번 바닐라 오브젝트 만 필요하다면이 패턴은 아마도 값을 추가하지 않을 것입니다.


답변

개체 초기화 비용을 제한하고 추가로 모든 함수 호출이 동일한 개체를 사용하도록 합니다. 예를 들어 향후 호출에서 사용할 수 있도록 상태를 객체에 저장할 수 있습니다.

메모리 사용량을 제한 할 수 있지만 일반적으로 GC는 어쨌든 사용하지 않는 개체를 수집하므로이 패턴은 그다지 도움이되지 않습니다.

이 패턴은 특정 형태의 폐쇄 입니다.


답변

이 패턴의 이름이 더 정확한지 확실하지 않지만 이것은 나에게 모듈처럼 보이며 사용되는 이유는 캡슐화하고 상태를 유지하기위한 것입니다.

클로저 (함수 내 함수로 식별 됨)는 내부 함수가 외부 함수 내 변수에 액세스 할 수 있도록합니다.

제공 한 예제에서 내부 함수는 foo외부 함수를 실행하여 반환되고에 할당됩니다. 즉 tmpObject, 클로저 내에서 계속 존재하고 내부 함수에 대한 여러 호출이 foo()의 동일한 인스턴스에서 작동합니다 tmpObject.


답변

코드와 Three.js 코드의 주요 차이점은 Three.js 코드에서 변수 tmpObject는 한 번만 초기화 된 다음 반환 된 함수를 호출 할 때마다 공유된다는 것입니다.

이것은 staticC와 유사한 언어에서 변수가 사용되는 방식과 유사하게 호출 사이에 일부 상태를 유지하는 데 유용 합니다.

tmpObject 내부 함수에서만 볼 수있는 개인 변수입니다.

메모리 사용량을 변경하지만 메모리를 절약하도록 설계되지 않았습니다.


답변

모든 메서드와 변수가 명시 적으로 노출 될 때까지 비공개로 유지되도록하는 공개 모듈 패턴의 개념으로 확장하여이 흥미로운 스레드에 기여하고 싶습니다.

여기에 이미지 설명 입력

후자의 경우 더하기 메서드는 Calculator.add ();


답변

제공된 예제에서 첫 번째 스 니펫은 foo () 함수를 호출 할 때마다 동일한 tmpObject 인스턴스를 사용합니다. 두 번째 스 니펫에서와 마찬가지로 tmpObject는 매번 새 인스턴스가됩니다.

첫 번째 조각이 사용되었을 수있는 한 가지 이유는 변수 tmpObject가 foo ()가 선언 된 범위로 값이 유출되지 않고 foo () 호출간에 공유 될 수 있다는 것입니다.

첫 번째 스 니펫의 즉시 실행되지 않는 함수 버전은 실제로 다음과 같습니다.

var tmpObject = new Bar();

function foo(){
    // Use tmpObject.
}

그러나이 버전에는 foo ()와 동일한 범위에 tmpObject가 있으므로 나중에 조작 할 수 있습니다.

동일한 기능을 달성하는 더 좋은 방법은 별도의 모듈을 사용하는 것입니다.

모듈 ‘foo.js’:

var tmpObject = new Bar();

module.exports = function foo(){
    // Use tmpObject.
};

모듈 2 :

var foo = require('./foo');

IEF와 명명 된 foo 생성자 함수의 성능 비교 : http://jsperf.com/ief-vs-named-function


답변