検索

JSにおけるクロージャの簡単な説明

Oct 24, 2017 am 09:44 AM
javascriptについて説明する

1.「クロージャーはスコープを越えて変数にアクセスしています。」

【例1】


var name = 'wangxi'
function user () {
 // var name = 'wangxi'
 function getName () {
 console.log(name)
 }
 getName()
}
user() // wangxi

getName関数で名前を取得するには、まずgetName関数のスコープ内で名前を検索しますが、見つかりません。その後、ユーザー関数のスコープ内で検索しましたが、やはり見つかりませんでした。さらに上に遡って、グローバル スコープ内に名前が存在することがわかったので、名前の値を取得して出力しました。ここで理解するのは簡単です。つまり、変数が指定されたスコープ内に存在する場合、現在のスコープ内で目的の変数が見つからない場合、同じ名前を持つ最初の変数が見つかるまで、スコープ チェーンを通じて親スコープ内で検索が続行されます。変数が見つかりました (見つからない場合は ReferenceError がスローされます)。これは JS のスコープ チェーンの概念です。つまり、子スコープはスコープ チェーンに従って親スコープの変数にアクセスできます。逆に、親スコープが子スコープの変数にアクセスしたい場合はどうなるでしょうか。 ——これは閉鎖によって達成する必要があります。

【例 2】


function user () {
 var name = 'wangxi'
 return function getName () {
 return name
 }
}
var userName = user()()
console.log(userName) // wangxi

コードを分析すると、name はユーザー関数のスコープ内に存在するローカル変数であることがわかります。通常の状況では、name 変数は外部スコープではアクセスできません。グローバル) ですが、クロージャ (変数を含む関数を返す、ここでは getName 関数) を通じて、スコープを越えて変数にアクセスできます (外部から内部へのアクセス)。したがって、上記のステートメントは次のように完全に理解される必要があります:

クロージャーとは、スコープを越えて変数にアクセスすることを意味します。内部スコープは外部スコープの変数への参照を維持できるため、外部スコープは (さらに) の内部スコープ変数にアクセスできます。 (それでも理解できない場合は、次の分析を読んでください)

2. 「結論: お父さんはおじいちゃんの環境で処刑され、孫はお父さんの環境に戻されます。もともと、お父さんは処刑されており、お父さんの環境はをクリアする必要がありますが、孫が父親の環境を参照したため、父親はそれを解放できませんでした。簡単に言うと、クロージャは親の環境を参照して上位の環境に返すオブジェクトです。これわかりますか?まず以下のコードを見てください:

[例 3]

function user () {
 var name = 'wangxi'
 return name
}
var userName = user()
console.log(userName) // wangxi

Q: これはクロージャですか?

A: もちろん違います。まず、クロージャとは何かを理解する必要があります。ユーザー関数内のローカル変数名はグローバルスコープでアクセスしているように見えますが、問題はユーザー実行後に名前も破棄されてしまうこと、つまり関数内のローカル変数のライフサイクルがDuring中にしか存在しないことです。関数の宣言サイクルが完了すると、関数は破棄され、関数内の変数は自動的に破棄されます。

しかし、クロージャを使用するとその逆になります。関数が実行された後、ライフサイクルは終了しますが、クロージャによって参照される外側のスコープ内の変数はまだ存在し、クロージャを実行するスコープが破棄されるまで常に存在します。ローカル変数は破棄されます (クロージャがグローバル環境で参照されている場合、クロージャによって参照されるスコープは、プログラムの終了時やブラウザの閉じ時など、グローバル環境が破棄された場合にのみ破棄されます)。したがって、クロージャによるメモリ損失を避けるために、使用後にクロージャを手動で破棄することをお勧めします。上記の例 2 と同じですが、少し変更されています:

[例 4]

function user () {
 var name = 'wangxi'
 return function getName () {
 return name
 }
}
var userName = user()() // userName 变量中始终保持着对 name 的引用
console.log(userName) // wangxi
userName = null // 销毁闭包,释放内存

[user()() に 2 つの括弧がある理由: user() を実行すると getName 関数が返されます。 name 変数を取得するには、返された getName 関数は一度実行する必要があるため、 user()() です】

ポイント 2 に従って、コードを分析します。userName 変数 (grandpa) がグローバル スコープで作成され、ユーザーの最終的な戻り結果が返されます。関数は参照 (つまり、ローカル変数名の値) を保存し、user()() (お父さん) を実行し、user()() の実行後に名前 (孫) を返します。 (父) はクリアする必要があります。ただし、返された結果の名前 (孫) は父の環境を参照しているため (名前は元々ユーザーのスコープに存在するため)、ユーザーの環境を解放することはできません (メモリ損失が発生します)。

それで [「クロージャは、親環境を参照し、親環境から上位レベルの環境にオブジェクトを返すオブジェクトです。」] どう理解すればよいでしょうか?

別の言い方をしましょう: 関数が親環境のオブジェクトを参照し、この関数内でそのオブジェクトを上位レベルの環境に返す場合、この関数はクロージャです。

上記の例を見てください:

getName 関数は、ユーザー (親) 環境のオブジェクト (変数名) を参照し、関数内でその name 変数をグローバル環境 (上位環境) に返します。 getName クロージャです。

3. 「JavaScript の関数は、実行されるスコープではなく、定義されているスコープで実行されます。」 この文は、クロージャ内の変数への参照を非常に明確に理解しています。 。次の例を見てみましょう:

var name = 'Schopenhauer'
function getName () {
 console.log(name)
}
function myName () {
 var name = 'wangxi'
 getName()
}
myName() // Schopenhauer

myName() を実行した出力結果が想像したものと異なる場合は、上の文を戻って読む必要があります

JavaScript 中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里

执行 myName,函数内部执行了 getName,而 getName 是在全局环境下定义的,因此尽管在 myName 中定义了变量 name,对getName 的执行并无影响,getName 中打印的依然是全局作用域下的 name。

我们稍微改一下代码:


var name = 'Schopenhauer'
function getName () {
  var name = 'Aristotle'
 var intro = function() { // 这是一个闭包
  console.log('I am ' + name)
 }
 return intro
}
function showMyName () {
 var name = 'wangxi'
 var myName = getName()
 myName()
}
showMyName() // I am Aristotle

结果和你想象的一样吗?结果留作聪明的你自己分析~

以上就是对 js 中闭包的理解,如果有误,欢迎指正。最后引用一段知乎问题下关于闭包概念的一个回答。

什么是闭包?

简单来说,闭包是指可以访问另一个函数作用域变量的函数,一般是定义在外层函数中的内层函数。

为什么需要闭包?

局部变量无法共享和长久的保存,而全局变量可能造成变量污染,所以我们希望有一种机制既可以长久的保存变量又不会造成全局污染。

特点

  • 占用更多内存

  • 不容易被释放

何时使用?

变量既想反复使用,又想避免全局污染

如何使用?

  1. 定义外层函数,封装被保护的局部变量。

  2. 定义内层函数,执行对外部函数变量的操作。

  3. 外层函数返回内层函数的对象,并且外层函数被调用,结果保存在一个全局的变量中。

以上がJSにおけるクロージャの簡単な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

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インタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

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ヘンタイを無料で生成します。

ホットツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

Safe Exam Browser

Safe Exam Browser

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境