JavaScript에서 닫는 실용적인 용도는 무엇입니까?
나는 JavaScript 폐쇄에 대해 머리를 싸매기 위해 최선을 다하고 있다.
내부 함수를 반환하면 직계 부모에서 정의된 변수에 액세스할 수 있습니다.
이게 어디에 도움이 될까요?아마도 나는 아직 그것에 대해 잘 이해하지 못할 것이다.내가 온라인에서 본 대부분의 예들은 현실세계의 어떤 코드도 제공하지 않고 그저 모호한 예만 제공한다.
누가 폐쇄의 실제 사용법을 보여줄 수 있나요?
예를 들면 이거예요?
var warnUser = function (msg) {
var calledCount = 0;
return function() {
calledCount++;
alert(msg + '\nYou have been warned ' + calledCount + ' times.');
};
};
var warnForTamper = warnUser('You can not tamper with our HTML.');
warnForTamper();
warnForTamper();
사용자가 웹 페이지에서 단추를 클릭한 횟수를 세려고 합니다.
이를 위해 변수 카운트를 업데이트하기 위한 버튼 이벤트 시 함수를 트리거합니다.
<button onclick="updateClickCount()">click me</button>
다음과 같은 다양한 접근 방식이 있을 수 있습니다.
글로벌 변수와 카운터를 증가시키는 함수를 사용할 수 있습니다.
var counter = 0; function updateClickCount() { ++counter; // Do something with counter }
단, 페이지 상의 스크립트는 호출하지 않고 카운터를 변경할 수 있습니다.
이 경우 함수 내에 변수를 선언할 수 있습니다.
function updateClickCount() { var counter = 0; ++counter; // Do something with counter }
매번 ★★★★★★★★★★★★★★★★★★★★★★★★★★★.
updateClickCount()
함수가 호출되고 카운터가 다시 1로 설정됩니다.
중첩된 기능을 생각하고 있습니까?
중첩된 함수는 "위" 범위에 액세스할 수 있습니다.
예에서는, 함수 「」가 되고 있습니다.
updateClickCount()
함수의 할 수 있습니다.countWrapper()
:function countWrapper() { var counter = 0; function updateClickCount() { ++counter; // Do something with counter } updateClickCount(); return counter; }
카운터의할 수 .
updateClickCount()
.counter = 0
매이아아아아니번번번번번번번 。
구조 종료! (자체 호출 기능):
var updateClickCount = (function(){ var counter = 0; return function(){ ++counter; // Do something with counter } })();
을 사용하다「 」가됩니다.
counter
0으로 하다입니다.
updateClickCount
함수가 됩니다."원더풀" 부분은 부모 스코프의 카운터에 액세스할 수 있다는 것입니다.이를 JavaScript 클로저라고 합니다.함수가 "개인" 변수를 가질 수 있습니다.
counter
함수의 되며, 어나니머스 함수의 범위인 "" " " " " " 를 해야만 할 수 .updateClickCount()
기!!
폐쇄에 대한 보다 활발한 예
<script>
var updateClickCount = (function(){
var counter = 0;
return function(){
++counter;
document.getElementById("spnCount").innerHTML = counter;
}
})();
</script>
<html>
<button onclick="updateClickCount()">click me</button>
<div> you've clicked
<span id="spnCount"> 0 </span> times!
</div>
</html>
레퍼런스: JavaScript Closes
클로저를 사용해서 다음과 같은 일을 해왔습니다.
a = (function () {
var privatefunction = function () {
alert('hello');
}
return {
publicfunction : function () {
privatefunction();
}
}
})();
a
오브젝트입니다입니다.publicfunction
)a.publicfunction()
.privatefunction
(폐쇄 내부에만 존재합니다).전화를 걸 수 없습니다.privatefunction
직즉즉즉즉즉즉, directly directly directly)a.privatefunction()
만 해당됩니다.publicfunction()
.
최소한의 예이지만, 사용법을 알 수 있지 않을까요?우리는 이것을 공적/사적 방법을 적용하기 위해 사용했다.
당신이 제시한 예는 훌륭한 것입니다.폐쇄는 매우 깔끔하게 문제를 분리할 수 있는 추상화 메커니즘입니다.예를 들어 instrumentation(콜 카운트)을 semantics(에러 리포트 API)에서 분리하는 경우입니다.그 외의 용도에는 다음이 있습니다.
매개 변수화된 동작을 알고리즘으로 전달(고차 고전 프로그래밍):
function proximity_sort(arr, midpoint) { arr.sort(function(a, b) { a -= midpoint; b -= midpoint; return a*a - b*b; }); }
객체 지향 프로그래밍 시뮬레이션:
function counter() { var a = 0; return { inc: function() { ++a; }, dec: function() { --a; }, get: function() { return a; }, reset: function() { a = 0; } } }
jQuery의 이벤트 처리 및 AJAX API와 같은 이국적인 흐름 제어 구현
JavaScript closures를 사용하여 응용 프로그램에서 스로틀 및 디바운스 기능을 구현할 수 있습니다.
슬롯링
슬롯링에서는 함수가 시간에 따라 호출될 수 있는 최대 횟수로 제한됩니다.'100밀리초에 한 번 이 기능을 실행한다'와 같습니다.
코드:
const throttle = (func, limit) => {
let isThrottling
return function() {
const args = arguments
const context = this
if (!isThrottling) {
func.apply(context, args)
isThrottling = true
setTimeout(() => isThrottling = false, limit)
}
}
}
비난
디버깅은 특정 시간이 경과할 때까지 호출되지 않는 함수에 제한을 가합니다."이 함수는 호출되지 않고 100밀리초가 경과한 경우에만 실행"과 같습니다.
코드:
const debounce = (func, delay) => {
let debouncing
return function() {
const context = this
const args = arguments
clearTimeout(debouncing)
debouncing = setTimeout(() => func.apply(context, args), delay)
}
}
보시는 바와 같이 폐쇄는 원활한 UI 체험 기능을 제공하기 위해 모든 웹 애플리케이션이 필요로 하는 두 가지 아름다운 기능을 구현하는 데 도움이 됩니다.
아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 맞다. 호출에 User가 됩니다.calledCount
, 이 함수는 스코프의 변수에 .warnForTamper
에 함수 시되지 않기 때문에 called Count에 각 은 삭제되지 않습니다.warnForTamper()
는 범위 변수를 증가시키고 값을 경고합니다.
스택 오버플로우에서 가장 일반적인 문제는 루프마다 증가하는 변수의 사용을 '지연'하는 것입니다.다만, 변수의 범위가 지정되기 때문에 변수에 대한 각 참조는 루프가 종료된 후가 되어 변수의 종료 상태가 됩니다.
for (var i = 0; i < someVar.length; i++)
window.setTimeout(function () {
alert("Value of i was "+i+" when this timer was set" )
}, 10000);
인 '경보'가 됩니다.i
루프가 종료되었을 때의 값이 증가합니다.해결책은 변수에 대해 별도의 범위인 새 닫힘을 만드는 것입니다.이는 변수를 수신하여 인수로 상태를 저장하는 즉시 실행되는 익명 함수를 사용하여 수행할 수 있습니다.
for (var i = 0; i < someVar.length; i++)
(function (i) {
window.setTimeout(function () {
alert("Value of i was " + i + " when this timer was set")
}, 10000);
})(i);
특히 JavaScript(또는 ECMAScript) 언어에서 클로저는 인터페이스를 공개하면서 기능 구현을 숨기는데 유용합니다.
예를 들어 날짜 유틸리티 메서드의 클래스를 작성하고 있으며 사용자가 인덱스별로 평일 이름을 검색할 수 있지만 후드 아래에서 사용하는 이름 배열을 수정할 수는 없다고 가정합니다.
var dateUtil = {
weekdayShort: (function() {
var days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
return function(x) {
if ((x != parseInt(x)) || (x < 1) || (x > 7)) {
throw new Error("invalid weekday number");
}
return days[x - 1];
};
}())
};
에 주의:days
은 단순히 ''의 할 수 .dateUtil
오브젝트는 스크립트 사용자가 볼 수 있으며 소스 코드 없이도 원하는 경우 변경할 수 있습니다.단, 날짜 조회 기능을 반환하는 어나니머스 기능으로 둘러싸여 있기 때문에 조회 기능만으로 접근할 수 있기 때문에 조작이 방지되었습니다.
Mozilla Developer Network에는 Practical Closures 섹션이 있습니다.
오브젝트 지향적인 의미에서 클래스를 인스턴스화하는 개념(즉, 해당 클래스의 객체를 만드는 것)에 익숙하다면 폐쇄를 이해하는 데 가깝습니다.
이렇게 생각할 수 있습니다.두 개의 Person 객체를 인스턴스화하면 클래스 멤버 변수 "Name"이 인스턴스 간에 공유되지 않고 각 객체는 고유한 "복사"를 가집니다.마찬가지로 마감을 작성할 때 free 변수(위의 예에서는 calledCount)는 함수의 '인스턴스'에 바인딩됩니다.
warn User 함수에 의해 반환되는 모든 함수/클로저(그것은 고차 함수) 클로저가 같은 초기값(0)으로 'called Count'를 바인드하는 반면 클로저를 작성할 때는 종종 다른 이니셜라이저를 고차 함수에 전달하는 것이 더 유용하다는 사실에 의해 당신의 개념적인 비약이 약간 방해된다고 생각합니다.ke 다른 값을 클래스의 생성자에게 전달합니다.
따라서 'called Count'가 특정 값에 도달했을 때 사용자의 세션을 종료한다고 가정합니다.요구가 로컬네트워크에서 수신되는지 또는 대규모 불량인터넷에서 수신되는지에 따라 다른 값이 필요할 수 있습니다(예, 이는 의도된 예입니다).이를 실현하기 위해 calledCount의 다른 초기값을 warnUser(-3 또는 0?)에 전달할 수 있습니다.
문헌에 관한 문제의 일부는 문헌을 기술하는 데 사용되는 명명법("렉시컬 스코프", "자유 변수")이다.속지 마, 폐쇄는 보이는 것보다 더 간단해...프라이머 페이스;-)
여기 몇 번이고 하고 싶은 인사가 있습니다.클로저를 작성하면 해당 함수를 호출하여 그리팅을 녹음할 수 있습니다.폐쇄를 만들지 않으면 매번 내 이름을 전달해야 합니다.
종료하지 않는 경우(https://jsfiddle.net/lukeschlangen/pw61qrow/3/):
function greeting(firstName, lastName) {
var message = "Hello " + firstName + " " + lastName + "!";
console.log(message);
}
greeting("Billy", "Bob");
greeting("Billy", "Bob");
greeting("Billy", "Bob");
greeting("Luke", "Schlangen");
greeting("Luke", "Schlangen");
greeting("Luke", "Schlangen");
종료(https://jsfiddle.net/lukeschlangen/Lb5cfve9/3/):
function greeting(firstName, lastName) {
var message = "Hello " + firstName + " " + lastName + "!";
return function() {
console.log(message);
}
}
var greetingBilly = greeting("Billy", "Bob");
var greetingLuke = greeting("Luke", "Schlangen");
greetingBilly();
greetingBilly();
greetingBilly();
greetingLuke();
greetingLuke();
greetingLuke();
의 또 다른 입니다.this
특정 오브젝트에 대한 메서드에서 특정 오브젝트를 다른 곳(이벤트 핸들러 등)에서 호출할 수 있습니다.
function bind(obj, method) {
if (typeof method == 'string') {
method = obj[method];
}
return function () {
method.apply(obj, arguments);
}
}
...
document.body.addEventListener('mousemove', bind(watcher, 'follow'), true);
가 발생할 우스 whenever whenever whenever whenever whenever whenever whenever whenever whenever whenever whenever whenever whenever whenever whenever whenever whenever wheneverwatcher.follow(evt)
출됩니니다다
폐쇄는 또한 고차 함수의 필수적인 부분이며, 서로 다른 부분을 매개 변수화함으로써 유사한 여러 함수를 단일 고차 함수로 다시 쓰는 매우 일반적인 패턴을 가능하게 한다.추상적인 예로서
foo_a = function (...) {A a B}
foo_b = function (...) {A b B}
foo_c = function (...) {A c B}
된다
fooer = function (x) {
return function (...) {A x B}
}
여기서 A와 B는 구문 단위가 아니라 소스 코드 문자열(문자열 리터럴이 아님)입니다.
구체적인 예는 "함수에 의한 javascript 합리화"를 참조하십시오.
여기에서는, 폐사의 E-커머스 사이트나 그 외의 많은 사이트에서도 사용할 수 있는, 폐사의 개념의 간단한 예를 소개합니다.
예시와 함께 JSFiddle 링크를 추가합니다.3개 품목의 작은 상품 목록과 1개의 카트 카운터가 포함되어 있습니다.
// Counter closure implemented function;
var CartCouter = function(){
var counter = 0;
function changeCounter(val){
counter += val
}
return {
increment: function(){
changeCounter(1);
},
decrement: function(){
changeCounter(-1);
},
value: function(){
return counter;
}
}
}
var cartCount = CartCouter();
function updateCart() {
document.getElementById('cartcount').innerHTML = cartCount.value();
}
var productlist = document.getElementsByClassName('item');
for(var i = 0; i< productlist.length; i++){
productlist[i].addEventListener('click', function(){
if(this.className.indexOf('selected') < 0){
this.className += " selected";
cartCount.increment();
updateCart();
}
else{
this.className = this.className.replace("selected", "");
cartCount.decrement();
updateCart();
}
})
}
.productslist{
padding: 10px;
}
ul li{
display: inline-block;
padding: 5px;
border: 1px solid #DDD;
text-align: center;
width: 25%;
cursor: pointer;
}
.selected{
background-color: #7CFEF0;
color: #333;
}
.cartdiv{
position: relative;
float: right;
padding: 5px;
box-sizing: border-box;
border: 1px solid #F1F1F1;
}
<div>
<h3>
Practical use of a JavaScript closure concept/private variable.
</h3>
<div class="cartdiv">
<span id="cartcount">0</span>
</div>
<div class="productslist">
<ul>
<li class="item">Product 1</li>
<li class="item">Product 2</li>
<li class="item">Product 3</li>
</ul>
</div>
</div>
폐쇄 사용:
폐쇄는 JavaScript의 가장 강력한 기능 중 하나입니다.JavaScript는 함수의 중첩을 허용하고 내부 함수에 외부 함수에 정의된 모든 변수와 함수(및 외부 함수가 액세스할 수 있는 다른 모든 변수와 함수)에 대한 완전한 액세스를 부여합니다.그러나 외부 함수는 내부 함수에 정의된 변수 및 함수에 액세스할 수 없습니다.
이것은 내부 함수의 변수에 일종의 보안을 제공합니다.또한 내부 함수는 외부 함수의 범위에 접근할 수 있기 때문에 내부 함수가 외부 함수의 수명을 초과하여 생존할 수 있다면 외부 함수에 정의된 변수 및 함수는 외부 함수 자체보다 더 오래 존속한다.내부 기능이 외부 기능 외부의 스코프에서 사용할 수 있게 되면 폐쇄가 생성됩니다.
예를 들어:
<script>
var createPet = function(name) {
var sex;
return {
setName: function(newName) {
name = newName;
},
getName: function() {
return name;
},
getSex: function() {
return sex;
},
setSex: function(newSex) {
if(typeof newSex == "string" && (newSex.toLowerCase() == "male" || newSex.toLowerCase() == "female")) {
sex = newSex;
}
}
}
}
var pet = createPet("Vivie");
console.log(pet.getName()); // Vivie
console.log(pet.setName("Oliver"));
console.log(pet.setSex("male"));
console.log(pet.getSex()); // male
console.log(pet.getName()); // Oliver
</script>
위의 코드에서는 외부 함수의 이름 변수에 내부 함수가 접근할 수 있으며 내부 함수를 통해서만 내부 변수에 접근할 수 있습니다.내부 함수의 내부 변수는 내부 함수의 안전 저장소 역할을 합니다.내부 기능이 작동하기 위한 "영구적"이지만 안전한 데이터를 보유하고 있습니다.함수는 변수에 할당하거나 이름을 지정할 필요도 없습니다.자세한 내용은 여기를 참조하십시오.
JavaScript에서 클로징을 위한 실용적인 사용법 설명
다른 함수 내부에 함수를 만들 때 닫힘을 만듭니다.폐쇄는 외부 함수의 데이터를 읽고 조작할 수 있기 때문에 강력합니다.함수가 호출될 때마다 해당 콜에 대해 새로운 스코프가 생성됩니다.함수 내부에서 선언된 로컬 변수는 해당 범위에 속하며 해당 함수에서만 액세스할 수 있습니다.함수의 실행이 완료되면 스코프는 일반적으로 파기됩니다.
이러한 기능의 간단한 예는 다음과 같습니다.
function buildName(name) {
const greeting = "Hello, " + name;
return greeting;
}
위의 예에서는 buildName() 함수는 로컬 변수 그리팅을 선언하고 반환합니다.함수 호출마다 새로운 로컬 변수를 사용하여 새로운 스코프가 생성됩니다.함수 실행이 완료되면 해당 범위를 다시 참조할 방법이 없으므로 가비지가 수집됩니다.
하지만 그 범위에 대한 링크가 확보되면 어떻게 될까요?
다음 기능을 살펴보겠습니다.
function buildName(name) {
const greeting = "Hello, " + name + " Welcome ";
const sayName = function() {
console.log(greeting);
};
return sayName;
}
const sayMyName = buildName("Mandeep");
sayMyName(); // Hello, Mandeep Welcome
이 예에서 sayName() 함수는 closure입니다.sayName() 함수는 자체 로컬 스코프(변수 웰컴 포함)를 가지며 외부(폐쇄) 함수의 스코프에도 액세스할 수 있습니다.이 경우 buildName()로부터의 변수그리팅
buildName 실행 후 이 경우 스코프는 파기되지 않습니다.say MyName() 함수는 아직 액세스 권한이 있기 때문에 가비지 수집은 되지 않습니다.그러나 외부 스코프에서 데이터에 액세스하는 방법은 닫힘 이외에는 없습니다.폐쇄는 글로벌콘텍스트와 외부 스코프 사이의 게이트웨이로 기능합니다.
JavaScript 모듈 패턴은 클로저를 사용합니다.좋은 패턴으로 인해 유사한 "퍼블릭" 변수와 "프라이빗" 변수를 사용할 수 있습니다.
var myNamespace = (function () {
var myPrivateVar, myPrivateMethod;
// A private counter variable
myPrivateVar = 0;
// A private function which logs any arguments
myPrivateMethod = function(foo) {
console.log(foo);
};
return {
// A public variable
myPublicVar: "foo",
// A public function utilizing privates
myPublicFunction: function(bar) {
// Increment our private counter
myPrivateVar++;
// Call our private method using bar
myPrivateMethod(bar);
}
};
})();
저는 Mozilla의 함수 팩토리 예를 좋아합니다.
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var addFive = makeAdder(5);
console.assert(addFive(2) === 7);
console.assert(addFive(-5) === 0);
이 실마리는 폐쇄의 구조를 더 잘 이해하는 데 큰 도움이 되었습니다.
나는 그 후 몇 가지 실험을 했고, 이 꽤 간단한 코드를 생각해냈다.이 코드는 다른 사람들이 클로저가 어떻게 실용적인 방법으로 사용될 수 있는지, 그리고 어떻게 다른 수준에서 클로저를 사용하여 정적 변수 및/또는 글로벌 변수와 유사한 변수를 덮어쓰거나 글로벌 변수와 혼동될 위험 없이 유지하는지를 알 수 있도록 도와줄 수 있다.블레스
이를 통해 각 버튼의 로컬 수준과 글로벌 수준 모두에서 버튼 클릭을 추적하고 버튼 클릭을 한 번에 셀 수 있으므로 하나의 수치를 파악할 수 있습니다.이 작업에 글로벌 변수를 사용한 적이 없습니다.이것은 연습의 요점입니다.이것은, 글로벌한 것에 공헌하는 버튼에 적용할 수 있는 핸들러를 가지는 것입니다.
전문가 여러분, 제가 여기서 나쁜 일을 저질렀는지 알려주세요!저도 아직 배우고 있어요.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Closures on button presses</title>
<script type="text/javascript">
window.addEventListener("load" , function () {
/*
Grab the function from the first closure,
and assign to a temporary variable
this will set the totalButtonCount variable
that is used to count the total of all button clicks
*/
var buttonHandler = buttonsCount();
/*
Using the result from the first closure (a function is returned)
assign and run the sub closure that carries the
individual variable for button count and assign to the click handlers
*/
document.getElementById("button1").addEventListener("click" , buttonHandler() );
document.getElementById("button2").addEventListener("click" , buttonHandler() );
document.getElementById("button3").addEventListener("click" , buttonHandler() );
// Now that buttonHandler has served its purpose it can be deleted if needs be
buttonHandler = null;
});
function buttonsCount() {
/*
First closure level
- totalButtonCount acts as a sort of global counter to count any button presses
*/
var totalButtonCount = 0;
return function () {
// Second closure level
var myButtonCount = 0;
return function (event) {
// Actual function that is called on the button click
event.preventDefault();
/*
Increment the button counts.
myButtonCount only exists in the scope that is
applied to each event handler and therefore acts
to count each button individually, whereas because
of the first closure totalButtonCount exists at
the scope just outside, it maintains a sort
of static or global variable state
*/
totalButtonCount++;
myButtonCount++;
/*
Do something with the values ... fairly pointless
but it shows that each button contributes to both
its own variable and the outer variable in the
first closure
*/
console.log("Total button clicks: "+totalButtonCount);
console.log("This button count: "+myButtonCount);
}
}
}
</script>
</head>
<body>
<a href="#" id="button1">Button 1</a>
<a href="#" id="button2">Button 2</a>
<a href="#" id="button3">Button 3</a>
</body>
</html>
폐쇄에는 다양한 사용 사례가 있습니다.여기에서는 Closure 개념의 가장 중요한 사용법에 대해 설명하겠습니다.
- 폐쇄는 java, c++ 등의 객체 지향 언어처럼 개인 메서드 및 변수를 생성하기 위해 사용할 수 있습니다.개인 메서드 및 변수를 구현한 후에는 함수 내에 정의된 변수에 창 개체에서 액세스할 수 없습니다.이를 통해 데이터 은닉 및 데이터 보안에 도움이 됩니다.
const privateClass = () => {
let name = "sundar";
function setName(changeName) {
name = changeName;
}
function getName() {
return name;
}
return {
setName: setName,
getName: getName,
};
};
let javaLikeObject = privateClass(); \\ similar to new Class() in OOPS.
console.log(javaLikeObject.getName()); \\this will give sundar
javaLikeObject.setName("suresh");
console.log(javaLikeObject.getName()); \\this will give suresh
- 폐쇄의 또 다른 실제 예는 다음과 같습니다.
index.html 작성:
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Program with Javascript</title>
</head>
<body>
<p id="first"></p>
<p id="second"></p>
<button onclick="applyingConcepts()">Click</button>
<script src="./index.js"></script>
</body>
</html>
2) Index.js:
let count = 0;
return () => {
document.getElementById("first").innerHTML = count++;
};
})();
- 이 예에서는 버튼을 클릭하면 p#id로 카운트가 갱신됩니다.주의: 이 코드의 특별한 점은 무엇인지 궁금할 수 있습니다.검사 시 window 객체를 사용하여 카운트 값을 변경할 수 없다는 것을 알 수 있습니다.즉, private 변수 카운트를 선언하여 클라이언트에 의해 상태가 망가지는 것을 방지합니다.
나는 얼마 전에 폐쇄를 사용하여 이벤트 처리 코드를 간소화하는 방법에 대한 기사를 썼다.ASP를 비교합니다.클라이언트측 jQuery에 대한 NET 이벤트 처리.
http://www.hackification.com/2009/02/20/closures-simplify-event-handling-code/
프런트엔드의 JavaScript에 기술된 코드의 대부분은 이벤트 기반입니다.일부 동작을 정의하고 이를 사용자에 의해 트리거된 이벤트(클릭이나 키 누르기 등)에 첨부합니다.일반적으로 코드는 콜백으로 첨부됩니다.이벤트에 응답하여 실행되는 단일 함수입니다.size12, size14, size16은 본문 텍스트를 각각 12, 14, 16픽셀로 크기를 조정하는 함수입니다.다음과 같이 버튼(이 경우 링크)에 접속할 수 있습니다.
function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;
폐쇄는 발전기를 만드는 유용한 방법이며, 필요에 따라 시퀀스가 증가합니다.
var foobar = function(i){var count = count || i; return function(){return ++count;}}
baz = foobar(1);
console.log("first call: " + baz()); //2
console.log("second call: " + baz()); //3
차이는 다음과 같이 요약됩니다.
Anonymous 함수 정의된 함수 메서드로 사용할 수 없습니다. 객체의 메서드로 사용할 수 있습니다. 정의된 범위 내에만 존재합니다. 정의된 개체 내에 존재합니다. 정의된 범위 내에서만 호출할 수 있습니다. 코드의 임의의 지점에서 호출할 수 있습니다. 새 값을 재할당하거나 삭제할 수 있습니다. 삭제 또는 변경할 수 없습니다.
레퍼런스
클로징을 배우려고 하는데 제가 만든 예가 실용적인 사용 사례라고 생각합니다.스니펫을 실행하여 콘솔에서 결과를 볼 수 있습니다.
두 명의 개별 사용자가 별도의 데이터를 가지고 있습니다.각각 실제 상태를 보고 업데이트할 수 있습니다.
function createUserWarningData(user) {
const data = {
name: user,
numberOfWarnings: 0,
};
function addWarning() {
data.numberOfWarnings = data.numberOfWarnings + 1;
}
function getUserData() {
console.log(data);
return data;
}
return {
getUserData: getUserData,
addWarning: addWarning,
};
}
const user1 = createUserWarningData("Thomas");
const user2 = createUserWarningData("Alex");
//USER 1
user1.getUserData(); // Returning data user object
user1.addWarning(); // Add one warning to specific user
user1.getUserData(); // Returning data user object
//USER2
user2.getUserData(); // Returning data user object
user2.addWarning(); // Add one warning to specific user
user2.addWarning(); // Add one warning to specific user
user2.getUserData(); // Returning data user object
실제로 클로저는 다양한 계산, 지연 콜, 콜백, 캡슐화된 스코프 작성 등을 커스터마이즈할 수 있는 우아한 설계를 작성할 수 있습니다.
예를 들어 정렬 조건 함수를 인수로 받아들이는 배열 정렬 방식을 들 수 있습니다.
[1, 2, 3].sort(function (a, b) {
... // Sort conditions
});
기능 인수 조건에 따라 새 배열을 매핑하는 배열의 맵 방식으로서의 기능 매핑:
[1, 2, 3].map(function (element) {
return element * 2;
}); // [2, 4, 6]
검색 조건을 거의 무제한으로 정의하는 함수 인수를 사용하여 검색 기능을 구현하는 것이 편리합니다.
someCollection.find(function (element) {
return element.someProperty == 'searchCondition';
});
또, 예를 들면, 함수를 요소의 배열에 적용하는 forEach 메서드로서 기능을 적용하는 것에 주의할 수 있습니다.
[1, 2, 3].forEach(function (element) {
if (element % 2 != 0) {
alert(element);
}
}); // 1, 3
함수는 인수(적용시 인수 목록 및 콜시 포지셔닝된 인수)에 적용됩니다.
(function () {
alert([].join.call(arguments, ';')); // 1;2;3
}).apply(this, [1, 2, 3]);
지연된 콜:
var a = 10;
setTimeout(function () {
alert(a); // 10, after one second
}, 1000);
콜백 함수:
var x = 10;
// Only for example
xmlHttpRequestObject.onreadystatechange = function () {
// Callback, which will be called deferral ,
// when data will be ready;
// variable "x" here is available,
// regardless that context in which,
// it was created already finished
alert(x); // 10
};
보조 오브젝트를 숨기기 위해 캡슐화된 스코프를 만듭니다.
var foo = {};
(function (object) {
var x = 10;
object.getX = function _getX() {
return x;
};
})(foo);
alert(foo.getX()); // Get closured "x" – 10
주어진 샘플에서 둘러싸인 변수 '카운터'의 값은 보호되며 주어진 함수(증가, 감소)를 통해서만 변경할 수 있다.마감된 상태이기 때문에
var MyCounter = function (){
var counter = 0;
return {
increment:function () {return counter += 1;},
decrement:function () {return counter -= 1;},
get:function () {return counter;}
};
};
var x = MyCounter();
// Or
var y = MyCounter();
alert(x.get()); // 0
alert(x.increment()); // 1
alert(x.increment()); // 2
alert(y.increment()); // 1
alert(x.get()); // x is still 2
모두가 폐사의 실제 사용 사례인 정의와 몇 가지 예를 설명했습니다.
Closures의 사용 사례 목록을 투고하고 싶다.
- 버튼을 클릭하는 횟수를 카운트한다고 가정합니다. 닫는 것이 가장 좋습니다.
- 슬롯링 및 디바운스
- 카레잉
- 외우다
- 비동기 월드의 상태 유지
- 한 번과 같은 기능
- set 타임아웃
- 반복기
언급URL : https://stackoverflow.com/questions/2728278/what-is-a-practical-use-for-a-closure-in-javascript
'programing' 카테고리의 다른 글
Python에서 데몬을 작성하려면 어떻게 해야 하나요? (0) | 2022.11.06 |
---|---|
MySQL에서 열이 비어 있는지 또는 null인지 확인하려면 어떻게 해야 합니까? (0) | 2022.11.06 |
mariadb procedure phmyadmin 오류입니다. (0) | 2022.11.06 |
Windows에서 MariaDB와 NodeJs에 액세스하는 방법 (0) | 2022.11.06 |
윈도우 리터레이터를 롤링 또는 슬라이딩합니까? (0) | 2022.11.06 |