ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptのクロージャとは何ですか? JavaScriptクロージャの使い方は?

JavaScriptのクロージャとは何ですか? JavaScriptクロージャの使い方は?

伊谢尔伦
伊谢尔伦オリジナル
2017-07-20 15:10:321687ブラウズ

いわゆる「クロージャ」は、多くの変数とこれらの変数にバインドされた環境を持つ式 (通常は関数) を指します。したがって、これらの変数も式の一部です。
クロージャに関して、最も簡単に説明すると、ECMAScript では内部関数の使用が許可されています。つまり、関数定義と関数式は別の関数の関数本体に配置されます。さらに、これらの内部関数は、すべてのローカル変数、パラメータ、およびそれらが存在する外部関数で宣言された他の内部関数にアクセスできます。クロージャは、これらの内部関数の 1 つが、それらを含む外部関数の外側で呼び出されるときに形成されます。つまり、内側の関数は外側の関数が戻った後に実行されます。この内部関数が実行されるときも、ローカル変数、パラメーター、および外部関数の他の内部関数にアクセスする必要があります。これらのローカル変数、パラメータ、関数宣言の値は(最初は)外側の関数が戻ったときの値ですが、内側の関数の影響も受けます。
要するに、クロージャの機能は、out 関数が実行されて戻った後、out 関数の内部関数の実行には JavaScript のガベージ コレクション メカニズム GC が out 関数によって占有されているリソースを再利用するのをクロージャが阻止することです。 out 関数の変数に依存します。
クロージャの 2 つの特徴:
1. 関数変数への参照として - 関数が返されるときにアクティブ化されます。
2. クロージャは、関数が戻ったときにリソースを解放しないスタック領域です。
例 1:

<script type="text/javascript"> 
function setupSomeGlobals() { 
// Local variable that ends up within closure 
var num = 666; 
// Store some references to functions as global variables 
gAlertNumber = function() { alert(num); } 
gIncreaseNumber = function() { num++; } 
gSetNumber = function(x) { num = x; } 
} 
</script> 
<button onclick="setupSomeGlobals()">生成 - setupSomeGlobals()</button> 
<button onclick="gAlertNumber()">输出值 - gAlertNumber()</button> 
<button onclick="gIncreaseNumber()">增加 - gIncreaseNumber()</button> 
<button onclick="gSetNumber(5)">赋值5 - gSetNumber(5)</button>

例 2:

<script type="text/javascript"> 
function newClosure(someNum, someRef) { 
// Local variables that end up within closure 
var num = someNum; 
var anArray = [1,2,3]; 
var ref = someRef; 
return function(x) { 
num += x; 
anArray.push(num); 
alert(&#39;num: &#39; + num + 
&#39; nanArray &#39; + anArray.toString() + 
&#39; nref.someVar &#39; + ref.someVar); 
} 
} 
var closure1 = newClosure(40, {someVar:&#39; never-online&#39;}) 
var closure2 = newClosure(99, {someVar:&#39; BlueDestiny&#39;}) 
closure1(4) 
closure2(3) 
</script>

例 3:

<script language="javascript"> 
/* 声明一个全局变量 - getImgInPositionedDivHtml - 并将一次调用一个外部函数表达式返回的内部函数赋给它。 
这个内部函数会返回一个用于表示绝对定位的 DIV 元素包围着一个 IMG 元素 的 HTML 字符串,这样一来, 
所有可变的属性值都由调用该函数时的参数提供: 
*/ 
var getImgInPositionedDivHtml = (function(){ 
/* 外部函数表达式的局部变量 - buffAr - 保存着缓冲数组。这个数组只会被创建一次,生成的数组实例对内部函数而言永远是可用的 
因此,可供每次调用这个内部函数时使用。 
其中的空字符串用作数据占位符,相应的数据 
将由内部函数插入到这个数组中: 
*/ 
var buffAr = [ 
&#39;<div id="&#39;, 
&#39;&#39;, //index 1, DIV ID 属性 
&#39;" style="position:absolute;top:&#39;, 
&#39;&#39;, //index 3, DIV 顶部位置 
&#39;px;left:&#39;, 
&#39;&#39;, //index 5, DIV 左端位置 
&#39;px;width:&#39;, 
&#39;&#39;, //index 7, DIV 宽度 
&#39;px;height:&#39;, 
&#39;&#39;, //index 9, DIV 高度 
&#39;px;overflow:hidden;\"><img src=\"&#39;, 
&#39;&#39;, //index 11, IMG URL 
&#39;\" width=\"&#39;, 
&#39;&#39;, //index 13, IMG 宽度 
&#39;\" height=\"&#39;, 
&#39;&#39;, //index 15, IMG 调蓄 
&#39;\" alt=\"&#39;, 
&#39;&#39;, //index 17, IMG alt 文本内容 
&#39;\"><\/div>&#39; 
]; 
/* 返回作为对函数表达式求值后结果的内部函数对象。 
这个内部函数就是每次调用执行的函数 
- getImgInPositionedDivHtml( ... ) - 
*/ 
return (function(url, id, width, height, top, left, altText){ 
/* 将不同的参数插入到缓冲数组相应的位置: 
*/ 
buffAr[1] = id; 
buffAr[3] = top; 
buffAr[5] = left; 
buffAr[13] = (buffAr[7] = width); 
buffAr[15] = (buffAr[9] = height); 
buffAr[11] = url; 
buffAr[17] = altText; 
/* 返回通过使用空字符串(相当于将数组元素连接起来) 
连接数组每个元素后形成的字符串: 
*/ 
return buffAr.join(&#39;&#39;); 
}); //:内部函数表达式结束。 
})();//自调用 
alert(getImgInPositionedDivHtml);//显示返回的函数 
alert(getImgInPositionedDivHtml("img.gif","img",100,50,0,0,"Test")); 
</script>

説明: 重要なトリックは、インライン関数式を実行して追加の実行環境を作成し、関数を表現することです。式は外部コードの関数として使用されます。このとき、バッファ配列は関数式のローカル変数として定義されます。関数式は一度だけ実行する必要があり、配列は一度作成されると、それに依存する関数で再利用できます。

以上がJavaScriptのクロージャとは何ですか? JavaScriptクロージャの使い方は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。