検索
ホームページウェブフロントエンドjsチュートリアルJavaScriptの書き方と関数クロージャを詳しく解説

1. クロージャとは何ですか? クロージャは、別の関数のスコープ内の変数にアクセスできる関数です。

簡単に言うと、JavaScript では内部関数の使用が許可されています。つまり、関数定義と関数式は別の関数の関数本体に配置されます。さらに、これらの内部関数は、すべてのローカル変数、パラメータ、およびそれらが存在する外部関数で宣言された他の内部関数にアクセスできます。クロージャは、これらの内部関数の 1 つが、それらを含む外部関数の外側で呼び出されるときに形成されます。


2. 変数のスコープ

クロージャを理解するには、まず変数のスコープを理解する必要があります。

変数のスコープはグローバル変数とローカル変数の2種類に過ぎません。


JavaScript 言語の特別な点は、グローバル変数を関数内で直接読み取ることができることです。

内部関数のスコープチェーンには外部関数のスコープが含まれているため、内部関数は外部関数の変数にアクセスできます。

次のように理解することもできます。内部関数のスコープは外部関数のスコープに広がります。 function;

var n=999;
function f1(){
 alert(n);
}
f1(); // 999

一方、関数内のローカル変数は関数の外から読み取ることはできません。

function f1(){
 var n=999;
}
alert(n); // error

ここで注意すべき点があります。関数内で変数を宣言する場合は、var コマンドを使用する必要があります。これを使用しない場合、実際にはグローバル変数を宣言していることになります。

function f1(){
  n=999;
}
f1();
alert(n); // 999

3. クロージャを記述して使用するいくつかの方法

3.1. 関数に属性を追加します

function Circle(r) {
this.r = r;
}
Circle.PI = 3.14159;
Circle.prototype.area = function() {
return Circle.PI * this.r * this.r;
}
var c = new Circle(1.0);
alert(c.area()); //3.14159

3.2. このメソッドを使用して変数に値を代入します

var Circle = function() {
var obj = new Object();
obj.PI = 3.14159;
 
obj.area = function( r ) {
return this.PI * r * r;
}
return obj;
}
var c = new Circle();
alert( c.area( 1.0 ) ); //3.14159

、最も便利です。 var obj = {} は空のオブジェクトを宣言することです

var Circle={
"PI":3.14159,
"area":function(r){
return this.PI * r * r;
}
};
alert( Circle.area(1.0) );//3.14159

4. クロージャーの主な機能

クロージャーはさまざまな場所で使用できます。その最大の用途は 2 つです。1 つは前述したように関数内の変数を読み取ること、もう 1 つはこれらの変数の値をメモリに保持することです。

4.1. ローカル変数を外部から読み取るにはどうすればよいですか?

さまざまな理由により、関数内でローカル変数を取得する必要がある場合があります。ただし、前述したように、これは通常の状況では不可能であり、回避策によってのみ実現できます。

それは、関数の中に別の関数を定義することです。

function f1(){
  var n=999;
  function f2(){
    alert(n); // 999
  }
}

上記のコードでは、関数 f2 が関数 f1 の中に含まれています。このとき、f1 内のローカル変数はすべて f2 から見えます。ただし、その逆は機能しません。f2 内のローカル変数は f1 には見えません。これは、JavaScript 言語に特有の「チェーン スコープ」構造で、子オブジェクトはすべての親オブジェクトの変数をレベルごとに検索します。したがって、親オブジェクトのすべての変数は子オブジェクトから見えますが、その逆はありません。

f2 は f1 のローカル変数を読み取ることができるので、f2 が戻り値として使用される限り、f1 の外部にあるその内部変数を読み取ることはできません!

function f1(){
  var n=999;
  function f2(){
    alert(n);
  }
  return f2;
}
var result=f1();
result(); // 999

4.2. 変数の値をメモリに保持するにはどうすればよいですか?

function f1(){
  var n=999;
  nAdd=function(){n+=1}
  function f2(){
    alert(n);
  }
  return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000

このコードでは、result は実際にはクロージャ f2 関数です。これは 2 回実行され、1 回目の値は 999、2 回目の値は 1000 でした。これは、関数 f1 のローカル変数 n が常にメモリに格納され、f1 が呼び出された後に自動的にクリアされないことを証明します。

なぜこれが起こっているのですか?その理由は、f1 が f2 の親関数であり、f2 がグローバル変数に割り当てられているため、f2 は常にメモリ内に存在し、f2 の存在は f1 に依存するため、f1 は常にメモリ内にあり、削除されないためです。呼び出しが完了すると、ガベージ コレクション メカニズム (ガベージ コレクション) によってリサイクルされます。

このコードでもう 1 つ注目すべき点は、「nAdd=function(){n+=1}」という行です。まず、var キーワードが nAdd の前に使用されていないため、nAdd はローカル変数ではなくグローバル変数です。 。次に、nAdd の値は匿名関数であり、匿名関数自体もクロージャであるため、nAdd は関数の外部で関数内のローカル変数を操作できるセッターと同等です。

5. クロージャとこのオブジェクト

このオブジェクトをクロージャで使用すると、いくつかの問題が発生する可能性があります。匿名関数の実行はグローバルであるため、その this オブジェクトは通常 window を指します。 コードは次のとおりです:

var name = "The window";
var object = {
name:"My object",
getNameFun:function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFun(){}); //"The window"(在非严格模式下)

this オブジェクトをクロージャがアクセスできる変数の外部スコープに保存します。アクセスするとオブジェクトが消えてしまいます。コードは次のとおりです:

var name = "The window";
var object = {
name:"My object",
getNameFun:function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFun(){}); //“My object”

6. クロージャとメモリ リーク

具体的には、HTML 要素がクロージャのスコープに格納されている場合、その要素は破棄できないことを意味します。以下のように:

function assignHandler(){
var element = document.getElementById("someElement");
element.onclick = function(){
alert(element.id);
}
}


上記のコードは要素イベント ハンドラーとしてクロージャを作成し、このクロージャは循環参照を作成します。無名関数は assignHandler() のアクティブオブジェクトへの参照を保存するため、要素への参照数を減らすことができません。無名関数が存在する限り、要素の参照番号は少なくとも 1 であるため、それによって占有されているメモリは再利用されません。

コードを書き直すことで、内部のリサイクル不可能性の問題を解決します。

function assignHandler(){
var element = document.getElementById("someElement");
var id = element.id;
element.onclick = function(){
alert(id);
}
element = null;
}

上記のコードは、クロージャが要素を直接参照しないことと、参照が関数を含むアクティブなオブジェクトに保存されることを認識しています。したがって、要素変数を null に設定して、要素変数が占有するメモリを正常にリサイクルできるようにする必要があります。

7. クロージャーの使用に関する注意事項

1) クロージャは関数内の変数をメモリに格納し、大量のメモリを消費するため、クロージャを悪用することはできません。悪用しないと、Web ページでパフォーマンスの問題が発生し、IE でメモリ リークが発生する可能性があります。解決策は、関数を終了する前に、未使用のローカル変数をすべて削除することです。

2) クロージャは、親関数内の変数の値を親関数の外に変更します。したがって、親関数をオブジェクトとして使用し、クロージャをそのパブリック メソッドとして使用し、内部変数をプライベート値として使用する場合は、親関数内の変数の値を自由に変更しないように注意する必要があります。

以上は編集者が紹介したJavaScriptのクロージャの書き方と機能について詳しく説明しました。ご質問があればメッセージを残していただければ編集者が返信させていただきます。時間。また、PHP 中国語 Web サイトをサポートしていただきありがとうございます。

JavaScript のクロージャの書き方と機能の詳細な説明については、PHP 中国語 Web サイトを参照してください。

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

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

JavaScript:Web言語の汎用性の調査JavaScript:Web言語の汎用性の調査Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

JavaScriptの進化:現在の傾向と将来の見通しJavaScriptの進化:現在の傾向と将来の見通しApr 10, 2025 am 09:33 AM

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

javascriptの分解:それが何をするのか、なぜそれが重要なのかjavascriptの分解:それが何をするのか、なぜそれが重要なのかApr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

pythonまたはjavascriptの方がいいですか?pythonまたはjavascriptの方がいいですか?Apr 06, 2025 am 12:14 AM

Pythonはデータサイエンスや機械学習により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、簡潔な構文とリッチライブラリエコシステムで知られており、データ分析とWeb開発に適しています。 2。JavaScriptは、フロントエンド開発の中核です。 node.jsはサーバー側のプログラミングをサポートしており、フルスタック開発に適しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)