JavaScriptの基礎(6) 関数式クロージャ_JavaScriptスキル
実際、js が関数クロージャーをサポートする主な理由は、js がデータを保存できる関数を必要とするためです。ここでの保存データとは、関数終了後に関数内の変数の値のみが保存されるものです。なぜ js が関数内にデータを保存できる必要があるのかというと、js は関数型言語だからです。関数内にデータを保存することは、関数型言語の特徴です。
前に紹介した関数を定義する 3 つの方法を確認してください
functiosu(numnumreturnunum//関数宣言構文定義
vasufunction(numnum)returnunum}//関数式定義
vasuneFunction("num""num""returnunum")//Functio コンストラクター
クロージャを分析する前に、まず関数の定義と呼び出しにおけるよくある間違いを見てみましょう。
例 1:
sayHi(); //错误:函数还不存在 var sayHi = function () { alert("test"); };
例 2:
if (true) { function sayHi() { alert("1"); } } else { function sayHi() { alert("2"); } } sayHi();//打印结果并不是我们想要的
例 3:
var fun1 = function fun2() { alert("test"); } fun2();//错误:函数还不存在
例 1 では、関数宣言構文を使用して関数を定義する前に関数を呼び出すことはできません。解決策:
1. 関数式を使用して関数を定義する場合は、式を定義した後に関数を呼び出す必要があります。
var sayHi = function () { alert("test"); }; sayHi()
2. 関数宣言を使用します。 (ここでは、ブラウザ エンジンが関数宣言をプロモートし、すべてのコードが実行される前に関数宣言を読み取ります)
sayHi(); function sayHi () { alert("test"); };
例 2 では、期待される結果は 1 を出力するはずですが、実際の結果は 2 を出力します。
if (true) { function sayHi() { alert("1"); } } else { function sayHi() { alert("2"); } } sayHi();//打印结果并不是我们想要的
なぜこのようなことが起こっているのでしょうか?関数宣言のプロモーションにより、ブラウザーは事前解析中に if 条件を判断せず、2 番目の関数定義を解析するときに最初の if 条件を直接上書きします。
解決策:
var sayHi; if (true) { sayHi = function () { alert("1"); } } else { sayHi = function () { alert("2"); } } sayHi();
例 3 では、fun1() のみを使用して呼び出すことができ、fun2() を呼び出すことはできないことがわかりました。
私自身の理解では、本当の理由はわかりません。情報は見つかりませんでした。
次の図に示すように、1: function fun3() { }; は var fun3 = function fun3() { }; と同等であるためです。
つまり、fun1() のみを使用して呼び出すことができ、fun2() を呼び出すことはできません。
実は、まだ質問があるのですが?知っている人がいたら教えてください。
fun2 は外部から呼び出せないのに、なぜ関数内から呼び出せるのでしょうか?ただし、デバッガではまだ fun1 を取得できません。
それでは、上記の 3 つの質問について準備をしていきましょう。今日は「閉店」の話を続けましょう。
定義: 別の関数のスコープ内の変数にアクセスできる関数です
関数の例から始めましょう:
例 1:
function fun() { var a = "张三"; } fun();//在我们执行完后,变量a就被标记为销毁了
function fun() { var a = "张三"; return function () { alert("test"); } } var f = fun();//同样,在我们执行完后,变量a就被标记为销毁了
function fun() { var a = "张三"; return function () { alert(a); } } var f = fun();//【现在情况发生变化了,如果a被销毁,显然f被调用的话就不能访问到变量a的值了】 f();//【然后变量a的值正常的被访问到了】 //这就是闭包,当函数A 返回的函数B 里面使用到了函数A的变量,那么函数B就使用了闭包。 示例: function fun() { var a = "张三"; return function () { alert(a); } } var f = fun();//【现在情况发生变化了,如果a被销毁,显然f被调用的话就不能访问到变量a的值了】 f();//【然后变量a的值正常的被访问到了】
図: (スコープ チェーンを理解していない学生は、まず前回の記事「スコープとスコープ チェーン」を読んでください)
例: (つまり、名前のない関数)
オブジェクト内の関数の戻り値が匿名関数の場合の奇妙な現象について
説明する前に、まず頭を整理して、読みながらさらに混乱しないようにしてください。混乱している場合は、次の内容は無視してください。
var name1 = "张三"; var obj = { name1: "李四", fun2: function () { alert(this.name1); }, fun3: function () { return function () { alert(this.name1); } } }
//本当に混乱しています。これは全体的な状況を示していますか?
前に「どのオブジェクトがメソッドをクリックしても、これがオブジェクトである」と述べましたが、obj.fun3()() は「Zhang San」を出力します。これは、グローバル スコープを実行することを意味します。
以下の例を見るとその理由がわかるかもしれません。
obj.fun3()() を分解してみましょう。まず、obj.fun3() はウィンドウ スコープに匿名関数を返し、これを呼び出してウィンドウを指します。 (ちょっと強引な説明になっている気がしますし、正しいかどうかわかりませんが、今のところはこんな感じです)
クロージャ形成の原因: メモリ解放の問題
一般に、関数が実行されると、ローカルのアクティブ オブジェクトは破棄され、グローバル スコープのみがメモリに保存されますが、クロージャの場合は状況が異なります。
クロージャのアクティブオブジェクトは引き続きメモリに格納されるため、上記の例では、関数呼び出しが戻った後、変数 i はアクティブオブジェクトに属します。これは、そのスタック領域が解放されていないことを意味しますが、 c() を呼び出します。 i 変数によって保存されたスコープ チェーンがグローバルに b()->a()-> になると、スコープ var i 宣言が検索され、次に var i=1; が見つかります。クロージャ ++i; 結果、最終出力値は 2 です。
上記は、編集者が共有した JavaScript の基本パート 6 の関数式クロージャです。気に入っていただければ幸いです。
ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

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

ホットトピック









フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

スキルや業界のニーズに応じて、PythonおよびJavaScript開発者には絶対的な給与はありません。 1. Pythonは、データサイエンスと機械学習でさらに支払われる場合があります。 2。JavaScriptは、フロントエンドとフルスタックの開発に大きな需要があり、その給与もかなりです。 3。影響要因には、経験、地理的位置、会社の規模、特定のスキルが含まれます。

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

同じIDを持つ配列要素をJavaScriptの1つのオブジェクトにマージする方法は?データを処理するとき、私たちはしばしば同じIDを持つ必要性に遭遇します...

この記事の視差スクロールと要素のアニメーション効果の実現に関する議論では、Shiseidoの公式ウェブサイト(https://www.shisido.co.co.jp/sb/wonderland/)と同様の達成方法について説明します。

Console.log出力の違いの根本原因に関する詳細な議論。この記事では、Console.log関数の出力結果の違いをコードの一部で分析し、その背後にある理由を説明します。 �...

JavaScriptを学ぶことは難しくありませんが、挑戦的です。 1)変数、データ型、関数などの基本概念を理解します。2)非同期プログラミングをマスターし、イベントループを通じて実装します。 3)DOM操作を使用し、非同期リクエストを処理することを約束します。 4)一般的な間違いを避け、デバッグテクニックを使用します。 5)パフォーマンスを最適化し、ベストプラクティスに従ってください。

フロントエンドのVSCodeと同様に、パネルドラッグアンドドロップ調整機能の実装を調べます。フロントエンド開発では、VSCODEと同様のVSCODEを実装する方法...
