ホームページ ウェブフロントエンド jsチュートリアル JavaScriptの基礎(6) 関数式クロージャ_JavaScriptスキル

JavaScriptの基礎(6) 関数式クロージャ_JavaScriptスキル

May 16, 2016 pm 03:26 PM

実際、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. クロージャとは何ですか?

定義: 別の関数のスコープ内の変数にアクセスできる関数です

関数の例から始めましょう:

例 1:

function fun() {
  var a = "张三";
}
fun();//在我们执行完后,变量a就被标记为销毁了
ログイン後にコピー
例 2:

function fun() {
  var a = "张三";
  return function () {
    alert("test");
  }
}
var f = fun();//同样,在我们执行完后,变量a就被标记为销毁了
ログイン後にコピー
例 3:

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的值正常的被访问到了】
ログイン後にコピー
明らかに、クロージャを誤って使用するとメモリ使用量が増加します。したがって、特別な状況を除いてクロージャを使用しないようにしてください。使用する場合は、メモリをリサイクルできるように、必ず手動で null 参照を設定してください。 f = null ;

図: (スコープ チェーンを理解していない学生は、まず前回の記事「スコープとスコープ チェーン」を読んでください)

2. 匿名関数とは何ですか? (概念の説明のみ)

例: (つまり、名前のない関数)

オブジェクト内の関数の戻り値が匿名関数の場合の奇妙な現象について

説明する前に、まず頭を整理して、読みながらさらに混乱しないようにしてください。混乱している場合は、次の内容は無視してください。

var name1 = "张三";
var obj = {
  name1: "李四",      
  fun2: function () {
    alert(this.name1);
  },
  fun3: function () {
    return function () {
      alert(this.name1);
    }
  }
}
ログイン後にコピー
obj.fun2();//印刷結果「李思」は期待どおりです。
obj.fun3()();//ここで返されるのは関数であるため、それを呼び出すには () のペアを追加する必要があります。印刷された結果は、予想外の「Zhang San」でした。

//本当に混乱しています。これは全体的な状況を示していますか?
前に「どのオブジェクトがメソッドをクリックしても、これがオブジェクトである」と述べましたが、obj.fun3()() は「Zhang San」を出力します。これは、グローバル スコープを実行することを意味します。

以下の例を見るとその理由がわかるかもしれません。

obj.fun3()() を分解してみましょう。まず、obj.fun3() はウィンドウ スコープに匿名関数を返し、これを呼び出してウィンドウを指します。 (ちょっと強引な説明になっている気がしますし、正しいかどうかわかりませんが、今のところはこんな感じです)

クロージャ形成の原因: メモリ解放の問題

一般に、関数が実行されると、ローカルのアクティブ オブジェクトは破棄され、グローバル スコープのみがメモリに保存されますが、クロージャの場合は状況が異なります。

クロージャのアクティブオブジェクトは引き続きメモリに格納されるため、上記の例では、関数呼び出しが戻った後、変数 i はアクティブオブジェクトに属します。これは、そのスタック領域が解放されていないことを意味しますが、 c() を呼び出します。 i 変数によって保存されたスコープ チェーンがグローバルに b()->a()-> になると、スコープ var i 宣言が検索され、次に var i=1; が見つかります。クロージャ ++i; 結果、最終出力値は 2 です。

上記は、編集者が共有した JavaScript の基本パート 6 の関数式クロージャです。気に入っていただければ幸いです。

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

ホット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衣類リムーバー

Video Face Swap

Video Face Swap

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? Apr 04, 2025 pm 02:42 PM

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

誰がより多くのPythonまたはJavaScriptを支払われますか? 誰がより多くのPythonまたはJavaScriptを支払われますか? Apr 04, 2025 am 12:09 AM

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

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

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

JavaScriptを使用して、同じIDを持つArray要素を1つのオブジェクトにマージする方法は? JavaScriptを使用して、同じIDを持つArray要素を1つのオブジェクトにマージする方法は? Apr 04, 2025 pm 05:09 PM

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

Shiseidoの公式Webサイトのように、視差スクロールと要素のアニメーション効果を実現する方法は?
または:
Shiseidoの公式Webサイトのようにスクロールするページを伴うアニメーション効果をどのように実現できますか? Shiseidoの公式Webサイトのように、視差スクロールと要素のアニメーション効果を実現する方法は? または: Shiseidoの公式Webサイトのようにスクロールするページを伴うアニメーション効果をどのように実現できますか? Apr 04, 2025 pm 05:36 PM

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

Console.log出力の違い結果:なぜ2つの呼び出しが異なるのですか? Console.log出力の違い結果:なぜ2つの呼び出しが異なるのですか? Apr 04, 2025 pm 05:12 PM

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

JavaScriptは学ぶのが難しいですか? JavaScriptは学ぶのが難しいですか? Apr 03, 2025 am 12:20 AM

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

フロントエンド開発でVSCodeと同様に、パネルドラッグアンドドロップ調整機能を実装する方法は? フロントエンド開発でVSCodeと同様に、パネルドラッグアンドドロップ調整機能を実装する方法は? Apr 04, 2025 pm 02:06 PM

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

See all articles