JavaScript에서 클로저가 중요한 이유는 무엇입니까?


16

C #의 람다 식도 닫혀 있지만 C # 커뮤니티 나 서적에서는 거의 논의되지 않습니다. C # 세계에서보다 훨씬 많은 JavaScript 사용자와 책이 클로저 에 대해 이야기하고 있습니다. 왜 그런 겁니까?


3
JavaScript는 일급 기능 언어로 취급되며 C #은 고전적인 OOP 언어입니다. 다른 패러다임, 다른 프로그래밍 스타일.
Raynos 2016 년

1
일급 기능을 갖는 것은 언어를 기능적 언어로 만듭니다. PHP (5.3 이후), 파이썬 또는 D에는 일급 기능이 있습니다. 그것들이 기능적인 언어라고 말할 수 있습니까? 물론 자바 스크립트도 아닙니다.
deadalnix 2016 년

1
@deadalnix JavaScript는 다중 패러다임 언어입니다. 주로 절차 적, 기능적 및 프로토 타입 OO 패러다임을 지원합니다. 그것은 결코 A의 순수 함수형 언어,하지만 당신은 쉽게 언어를 굽힘없이 기능적인 패러다임에서 자바 스크립트를 작성할 수 있습니다. C #과 python과 동일하게 말할 것입니다.
Raynos 2016 년

3
Y- 콤비 네이터를 정의 할 수있는 언어 인 @deadalnix는 기능적인 언어입니다. 정의에 의해.
SK-logic

1
@ deadalnix : 언어에 의해 어떤 접근법이 촉진 되는지에 대한 질문이라고 생각 합니다. 1 차 함수에 크게 의존하는 많은 JavaScript 프레임 워크 및 플랫폼 (특히 node.js 및 DOM (이벤트 모델))이 있습니다. PHP에는 동일한 프로그래밍 스타일을 허용하는 기능이 있지만 표준 API 또는 많은 프레임 워크를 살펴보면 언어의 핵심이 아니라는 것을 알 수 있습니다.
back2dos

답변:


5

자바 스크립트에는 네임 스페이스와 같은 기능이 없으므로 모든 종류의 전역 객체를 쉽게 엉망으로 만들 수 있습니다.

따라서 자체 실행 환경에서 일부 코드를 분리 할 수 ​​있어야합니다. 클로저는 완벽합니다.

이 클로저 사용법은 네임 스페이스, 클래스 등이 코드를 분리하고 모든 것을 글로벌 범위에 두지 않는 C #과 같은 언어에서는 의미가 없습니다.

자바 스크립트 코드에 대한 일반적인 관행은 다음과 같이 작성하는 것입니다.

(function(){
    // Some code
})();

보시다시피, 이것은 익명 함수 선언이며 즉시 실행됩니다. 따라서 함수 내에 정의 된 모든 것은 외부에서 액세스 할 수 없으며 전역 범위를 망칠 수 없습니다. 이 함수 내에서 정의 된 중첩 함수와 같이 일부 코드에서이를 사용하는 한이 함수의 실행 컨텍스트는 콜백 또는 기타로 전달할 수 있습니다.

자바 스크립트는 C #과 매우 다른 언어입니다. 객체 지향이 아니라 프로토 타입 지향입니다. 이것은 결국 매우 다른 관행으로 이어집니다.

어쨌든 클로저는 좋으므로 C #에서도 사용하십시오!

편집 : stackoverflow의 채팅에 대해 토론 한 후에이 anwer가 정밀해야한다고 생각합니다.

샘플 코드의 함수는 클로저가 아닙니다. 그러나이 기능은 로컬 변수 및 중첩 함수를 정의 할 수 있습니다. 이러한 지역 변수를 사용하는 모든 중첩 함수는 클로저입니다.

이것은 전역 범위를 망칠 필요없이 일련의 함수에서 일부 데이터를 공유하는 데 유용합니다. 이것은 자바 스크립트에서 가장 일반적으로 사용되는 클로저입니다.

클로저는 이와 같은 일부 데이터를 공유하는 것보다 훨씬 강력하지만 현실적으로 말하면 대부분의 프로그래머는 함수형 프로그래밍에 대해 알지 못합니다. C #에서는 이러한 종류의 용도로 클래스 또는 네임 스페이스를 사용했지만 JS는이 기능을 제공하지 않습니다.

전역 범위를 보호하는 것보다 클로저로 더 많은 것을 할 수 있지만 이것이 JS 소스 코드에서 볼 수 있습니다.


9
그것은 폐쇄가 아닙니다. 함수를 사용하여 로컬 범위를 만드는 이점을 설명합니다.
Raynos 2016 년

2
클로저는 자유 변수를 닫는 경우에만 클로저입니다. 또한 JavaScript가 어떻게 작동하는지 모르겠다는 말을 해주셔서 감사합니다 :)
Raynos

2
보다는 나에게 초보자를 호출하여 저를 훼손 의지는 앞으로 실제 인수를 넣어 주시기 자바 스크립트 SO 채팅 룸 . 이 토론은 실제로 여기에 속하지는 않지만 SO 채팅에서 오해를 기꺼이 논의합니다.
Raynos 2016 년

1
공감. JavaScript는 많은 객체 지향입니다. 클래스 기반은 아니지만 그러한 기능을 쉽게 작성할 수 있습니다. 그것은 일급 기능을 가지고 있으며, 폐쇄를 이용하여 이벤트 중심의 패러다임에 자연스럽게 맞고 저자 인 Brendan Eich에 따르면 주요 영감의 원천은 Scheme이었습니다. 함수형 언어가 무엇이라고 생각하는지 잘 모르겠지만 재미있는 부분은 함수를 전달하고 새로운 컨텍스트에 적용 할 때 클래스 기반 상속이 더 이상 완전히 필요하지 않다고 생각하는 것입니다.
Erik Reppen

2
-1도. 이것은 클로저를 설명하지 않고 범위를 설명합니다.
이즈 카타

12

JavaScript의 객체 지향에 대한 일반적인 구현은 클로저에 의존하기 때문일 수 있습니다. 간단한 예를 보자.

function counter() {
   var value = 0;
   this.getValue = function() { return value; }
   this.increase = function() { value++; }
}

var myCounter = new counter();
console.log(myCounter.getValue());
myCounter.increase();
console.log(myCounter.getValue());

메소드 getValueincrease변수는 실제로 캡슐화되어 있습니다 value.


3
-1 "폐쇄에 따라 다름"매우 주관적입니다. 그렇지 않습니다.
Raynos 2016 년

Raynos : 폐쇄없이 비공개 회원을 만들고 사용하는 방법을 알려주시겠습니까?
user281377 2016 년

1
@ammoQ JavaScript에는 private과 같은 것이 없습니다. "JavaScript 클래식 OO 에뮬레이션은 클로저에 의존하기 때문에"의미했습니다. JavaScript OO는 다른 패러다임 인 프로토 타입입니다. "
오래된

1
@keppla 나는 "OO는 클로저에 의존한다"는 주관적이라는 것을 의미했다. OO에 대한 폐쇄는 필요하지 않습니다.
Raynos

2
당신은 내가 대표 창녀로 나를 노출하고 있습니다 ...
user281377

4

JavaScript를 '가능하게 만드는'많은 라이브러리가이를 사용하기 때문입니다.

JQuery , Prototype 또는 MooTools를 살펴보면 세 가지 인기있는 이름을 지정할 수 있습니다. 각 라이브러리는 each반복자 함수를 사용하는 선호하는 반복 방법으로 콜렉션에 대한 메소드를 제공 합니다. 이 함수는 외부 범위의 값에 액세스 할 때 클로저가됩니다.

[1,2,3].each(function(item) {
   console.log(item);
});

Ajax의 콜백, Ext.js의 이벤트 처리 등은 모두 함수를 사용하며, 정확히 한 번만 호출되는 100ed 함수로 코드를 부풀리고 싶지 않다면 클로저를 사용하는 것이 좋습니다.


1
폐쇄가 아닌 이유는 무엇입니까? console.log외부 범위에서 정의되므로 console'자유 변수'입니다. 그리고 실제로 왜 효과가없는 for-loop가 나쁜 습관입니까?
keppla

@ Raynos : 클로저 정의는 '자유 변수를 포함하는 블록'이며, 그 상태를 풀지 않으며 자유 변수가 최상위 범위에 있습니다. 그러나 내 요지를 뒷받침하려면 다음 방법을 고려하십시오 : pastie.org/2144689 . 왜 이것이 나빠 야합니까?
keppla

여전히 글로벌 데이터에 대한 "폐쇄"는 부정 행위로 간주됩니다. 스코프 체인을 통해 데이터에 액세스하는 것이 좋습니다. 액세스를 최소화하는 것이 좋습니다.
Raynos 2016 년

액세스 최소화에 동의
keppla

배열 반복자 (각각, 맵, 축소 등)를 사용하면 클로저가 될 이유가 없으며 모든 상태가 직접 전달됩니다. 나는 그것이 폐쇄가되기위한 반 패턴으로 생각할 것이다
Raynos

3

JavaScript를 사용한 "좋은"코딩은 클로저에 더 크게 의존한다는 다른 답변에 동의합니다. 그러나 그 외에도 기능이 각 언어에서 얼마나 오랫동안 사용되었는지에 대한 질문 일 것입니다. JavaScript는 초기 구현 이후 기본적으로 폐쇄되었습니다. 반면 C #은 Visual Studio 2008과 함께 출시 된 3.0 이후로만 사용되었습니다.

내가 만나는 많은 C # 프로그래머는 여전히 2.0 프로젝트를 진행하고 있습니다. 3.0 또는 4.0에서 작업하더라도 2.0 관용구를 사용하는 경우가 많습니다. 나는 폐쇄를 좋아한다. 컨셉이 C # 개발자들 사이에서 전파됨에 따라 C #에서 더 많이 사용되기를 바랍니다.


2

주된 이유는 C #이 정적으로 유형이 지정되고 함수가 미리 결정된 단일 환경에만 액세스 할 수 있기 때문에 클로저의 유용성을 방해합니다.

반면 JavaScript에서는 클로저를 사용하면 객체 속성으로 액세스하고 일류 객체로 액세스 할 때 함수가 메소드로 작동 할 수 있으며 서브 루틴이 다른 컨텍스트에서 작동 할 수 있도록 다른 환경에 삽입 될 수도 있습니다.


1
정적 타이핑은 이것과 어떤 관련이 있습니까? 폐쇄는 직교입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.