분류 Nodejs

JavaScript에서 클로저 및 어휘 범위 지정에 대한 간략한 소개

컨텐츠 정보

  • 조회 306 (작성일 )

본문

이 기사에서는 JavaScript에서 클로저 및 어휘 범위를 설명합니다. 클로저를 이해하면 프로그래밍 자체를 더 잘 이해할 수 있습니다. 

전문 프로그래머가 될 계획이라면 기술 인터뷰 중에 클로저 및 해당 응용 프로그램에 대한 질문이 널리 제기되며 실제로 도움이 될 수 있습니다.


JavaScript 개발자 인 경우 이미 클로저를 사용하고 있을 가능성이 높습니다. 클로저를 배우려고 할 때 혼란스러워하는 복잡한 예제가 너무 많기 때문에 내가 찾을 수 있는 가장 간단한 예제를 사용하게 될 것입니다.이 글의 끝 부분에는 클로저가 무엇인지에 대한 기본적인 이해가 필요합니다. 


https://medium.com/better-programming/a-brief-introduction-to-closures-and-lexical-scoping-in-javascript-8a5866496232 


어휘 범위 


클로저에 대해 논의하기 전에 범위와 어휘 범위에 대한 기본적인 이해가 필요합니다. JavaScript에는 함수 범위를 사용한 어휘 범위가 있습니다. 즉, 각 함수는 새 범위를 만듭니다.


함수 범위란 무엇입니까? 


기본적으로 JavaScript에는 글로벌 범위 및 로컬 범위가 있습니다.


전역 범위 : Javascript 문서에는 전역 범위가 하나뿐입니다. 즉 모든 함수 외부의 영역과 전역 범위를 식별하는 방법은 전역 범위에 정의 된 변수가 코드의 어느 곳에서나 액세스 할 수 있다는 것입니다.


로컬 범위 : 함수 내에 선언 된 변수는 함수에 로컬이며 해당 로컬 범위에 바인딩됩니다. 이러한 변수는 함수 외부에서 액세스 할 수 없습니다.


예:

// global scope
let iHaveGlobalScope=`I can be accessed from anywhere in this document`
function localScope()
{
console.log(iHaveGlobalScope)
// lcoal scope1
let iHaveLocalScope=`I am bound to the local scope of function localScope`
}
console.log(localScope())
//I can be accessed from anywhere in this document
console.log(iHaveLocalScope)
//ReferenceError: iHaveLocalScope is not defined

글로벌 및 로컬 범위


변수 iHaveGlobalScope는 전역 범위에서 선언되므로 localScope() 함수 내에서도 액세스 할 수 있지만 변수 또는 로컬 범위 외부에 변수 iHaveLocalScope를 콘솔 로그하려고 하면 런타임에 참조 오류가 발생합니다.


로컬 범위는 함수 범위와 블록 범위로 더 나눌 수 있습니다. 블록 범위의 개념은 변수를 선언하는 새로운 방법인 const와 let과 함께 ES6에 도입되었습니다.


함수 범위 및 블록 범위 


함수 내에서 변수를 선언 할 때마다 변수는 함수 내에서 바인딩되며 함수 외부에서 변수에 액세스 할 수 없습니다. var는 함수 범위 접근성을 위한 변수를 정의하는 키워드입니다.


function functionScope(){
var iHaveFunctionScope=`something something mj`
console.log(iHaveFunctionScope)
}
functionScope()
//something something mj
console.log(iHaveFunctionScope);
//Reference Error


let 또는 const를 사용해도 오류가 발생하면 var가 함수 범위와 관련되는 이유는 무엇입니까? 문제는 let과 const가 블록 범위를 정의하는 데 사용되고 ES6 이전에는 JavaScript에 블록 범위나 let과 const가 없었습니다.


블록 범위는 if, 스위치 조건 또는 for 및 while 루프 내의 영역입니다. {curly brackets}가 보일 때마다 간단히 블록입니다.


예 :

function scope(){
if(true){
var scope1 =`I have function Scope`
let scope2 = `I have block scope`
const scope3 =`I also have block scope`
}
console.log(scope1)
console.log(scope2)
console.log(scope3)
}
scope()
//I have function Scope
//ReferenceError: scope2 is not defined
//ReferenceError: scope3 is not defined


이제는 어떤 로그 명령도 작동하지 않을 것으로 예상 할 수 있지만 var, var, if로 정의 된 변수, 스위치 조건 또는 for 및 while 루프에 대해 전역적으로 액세스 할 수 있고 전역 범위의 일부인 경우에는 그렇지 않습니다. 따라서 let과 const를 사용하는 것이 좋습니다.


어휘 범위 


마지막으로 이 게시물의 실제 목적에 도달했습니다. 글쎄, 나는 범위에 대한 긴 토론을 건너 뛸 수 있었지만 개인적으로 당신은 핵심 구성 요소를 중심으로 회전하는 어휘 범위를 이해할 수 있다고 생각하지 않습니다.


다시 한 번 기억해야 할 점은 Javascript에는 함수 범위에 대한 어휘 범위가 있습니다.


즉, 하위 범위가 상위 범위에 정의 된 변수에 액세스 할 수 있음을 의미합니다. 예를 들어, 함수를 정의하고 그 내부와 매우 동일한 함수 내에서 변수를 선언하려면 다른 함수를 정의하면 어휘 범위로 인해 내부 함수 내에서 해당 변수를 사용할 수 있어야 합니다. 예를 보자.


function outerFunction() {
var variable1 = 'ney vatsa'
const variable2 = 'shashank jha'
let variable3 = 'huda'
function innerFunction() {
console.log(variable1)
console.log(variable2)
console.log(variable3)
}
innerFunction()
}
outerFunction()
// ney vatsa
//shashank jha
//huda


예제에서 알 수 있듯이 outerFunction()에 선언 된 변수는 innerfunction()에 의해 액세스됩니다. 이것은 어휘 범위입니다.


변수의 범위는 코드에서의 위치에 따라 정의됩니다. 변수를 해결하기 위해 JavaScript는 가장 안쪽 범위에서 시작하여 찾고 있는 변수를 찾을 때까지 바깥쪽으로 검색합니다. 위 예제에서 Javascript는 먼저 innerFunction() 내부에서 변수를 검색하고 찾지 못하면 바깥쪽으로 이동합니다. 즉 outerFunction()


어휘 범위는 코드에서 변수의 값을 쉽게 알아낼 수 있기 때문에 더 좋습니다. 반면 동적 범위에서는 변수의 의미가 런타임에 변경되어 이해하기가 어렵습니다.


어휘 범위 지정이 무엇인지 이해했습니다. 이제 어휘 범위 지정이 실제로 사용되는 클로저를 살펴 보겠습니다.


Closures 


MDN (Mozilla Development Network)에 따르면 


“클로저는 함수와 해당 함수가 작성된 환경의 두 가지를 결합한 특별한 종류의 객체입니다. 환경은 클로저가 생성 될 당시 범위 내에 있던 모든 로컬 변수로 구성됩니다.” 


먼저 간단한 예제를 살펴 보겠습니다.


var outerFunction = function () {
let variable1 = "Example of closure"
var innerFunction = function () {
console.log(variable1)
}
return innerFunction;
}
var newFunction = outerFunction()
newFunction()
//Example of closure



여기서 생각할 요점은 outerFunction()은 innerFunction()을 반환하므로 newFunction()은 실제로 innerFunction()이지만 variable1을 반환하지 않았습니다. 여전히 newFunction()의 일부이므로 outerFunction()이 이미 반환 되어 실행이 끝난 경우 variable1의 값은 어디에서 오는가?


즉각적인 범위 밖의 변수에 액세스하면 클로저가 발생합니다. 


variable1은 innerFunction()을 작성한 어휘 환경의 일부이므로 innerFunction()에 액세스 할 수 있습니다.


다른 예를 보겠습니다.


function add(x) {
return function(y) {
return x + y;
};
}
var addFive = add(5);
var addTen = add(10);
console.log(addFive(10)); // 15
console.log(addTen(10)); // 20


참고로, 이것은 클로저에 널리 사용되는 예제이며 많은 자습서를 찾을 수 있습니다. 여기서 x와 y의 합을 반환하는 매개 변수 y로 다른 함수를 반환하는 매개 변수 x로 add() 함수를 정의했습니다.


이제 add() 함수 내에 인수를 전달하여 addFive() 및 addTen() 함수를 새로 작성합니다. 이러한 addTen() 및 addFive()는 실제로 클로저이며 동일한 함수 본문 정의를 갖지만 다른 어휘 환경을 저장합니다. addFive() 어휘 환경에서 x는 5이고 addTen()의 어휘 환경에서 x는 10입니다.


클로저는 JavaScript뿐만 아니라 모든 프로그래밍 언어에서 프로그래밍의 매우 중요한 부분입니다. 그것들은 객체 데이터 프라이버시, 이벤트 핸들러 및 콜백 함수 및 기타 기능적 프로그래밍 패턴과 같은 많은 실제 응용 프로그램을 가지고 있습니다.


JavaScript의 범위에 대한 기본 지식을 갖기를 바랍니다.이 게시물에서 어휘 범위 및 클로저에 대해 간략하게 소개했습니다. 다음 포스트에서는 다양한 예제를 통해 클로저와 데이터 프라이버시, call(), bind(), apply(), 이벤트 핸들러 등과 같은 실제 사용법에 대해 자세히 설명합니다.