ホームページ  >  記事  >  ウェブフロントエンド  >  1 分でわかる JS クロージャー_JavaScript スキル

1 分でわかる JS クロージャー_JavaScript スキル

WBOY
WBOYオリジナル
2016-05-16 15:02:201331ブラウズ

クロージャとは何ですか?
最初にコードの一部を見てください:

function a(){
  var n = 0;
  function inc() {
    n++;
    console.log(n);
  }
  inc(); 
  inc(); 
}
a(); //控制台输出1,再输出2

シンプルにしてください。もう一度コードを見てみましょう:

function a(){
  var n = 0;
  this.inc = function () {
    n++; 
    console.log(n);
  };
}
var c = new a();
c.inc();  //控制台输出1
c.inc();  //控制台输出2

シンプルにしてください。

クロージャとは何ですか?これで閉店です!

別の関数のスコープ内の変数にアクセスできる関数はクロージャです。ここで、inc 関数はコンストラクター a 内の変数 n にアクセスするため、クロージャが形成されます。

もう一度コードを見てみましょう:

function a(){
  var n = 0;
  function inc(){
    n++; 
    console.log(n);
  }
  return inc;
}
var c = a();
c();  //控制台输出1
c();  //控制台输出2

その仕組みをご覧ください:

var c = couter()、この文 couter() は関数 inc を返します、この場合、この文は var c = inc;

と同等です。

c()、この文は inc() と同等です。、関数名は単なる識別子 (関数へのポインター) であり、() は実行機能。

次の 3 つの文の翻訳は、var c = inc; inc(); inc(); ですが、最初のコードとは異なりますか? いいえ。

クロージャとは何ですか?これで閉店です!

教科書のチュートリアルはすべて、最後の段落を使ってクロージャを説明することを好みますが、これが問題を複雑にしていると思います。ここで返されるのは関数名です。Tan Haoqiang の C/C++ プログラミングを見たことがない学生は、() を使用する場合と使用しない場合の違いをすぐには理解できないかもしれません。つまり、この書き方には独自の罠があります。この書き方はより洗練されていますが、それでも問題を単純化したいと思います。コード 1 とコード 2 を見てください。まだ関数呼び出しに苦労していますか?

なぜこのように書くのですか?
js の各機能は、外の世界から情報を取得できる小さな暗い部屋であることがわかっていますが、外の世界は内部の内容を直接見ることはできません。変数 n を小さな黒い部屋に置きます。 inc 関数を除いて、変数 n にアクセスする方法はありません。また、関数 a の外で同じ名前の変数 n を定義しても、これはいわゆる拡張です。 「カプセル化」 。

関数識別子incを返すのにreturnを使っているのは、inc関数はa関数の外で直接呼び出すことができないので、return incを外にリンクしているためで、これはコード2でもincを外にリンクしています。

よくある罠
これを見てください:

function createFunctions(){
  var result = new Array();
  for (var i=0; i < 10; i++){
    result[i] = function(){
      return i;
    };
  }
  return result;
}
var funcs = createFunctions();
for (var i=0; i < funcs.length; i++){
  console.log(funcs[i]());
}

一見、0~9を出力すると思っていましたが、まさか10の10を出力するとは?

ここでの罠は次のとおりです: () が付いた関数は実行関数です。 var f = function() {alert('Hi'); のような単純な文は、関数内のコードが続く場合にのみウィンドウを表示します。実行されました。上記のコードの翻訳は次のとおりです:

var result = new Array(), i;
result[0] = function(){ return i; }; //没执行函数,函数内部不变,不能将函数内的i替换!
result[1] = function(){ return i; }; //没执行函数,函数内部不变,不能将函数内的i替换!
...
result[9] = function(){ return i; }; //没执行函数,函数内部不变,不能将函数内的i替换!
i = 10;
funcs = result;
result = null;

console.log(i); // funcs[0]()就是执行 return i 语句,就是返回10
console.log(i); // funcs[1]()就是执行 return i 语句,就是返回10
...
console.log(i); // funcs[9]()就是执行 return i 语句,就是返回10

結果だけが収集され、私は収集されないのはなぜですか? i はまだ関数によって参照されているためです。レストランと同じように、皿の数には限りがあるため、ウェイターは空の皿を集めるためにテーブルを巡回しますが、野菜がまだ入っている皿を集めることができますか? もちろん、皿の上の皿を手動で空にすると(= null)、皿は取り去られます。これは、いわゆるメモリリサイクルのメカニズムです。

i の値がどのように保持されるかについては、実際、記事の最初から最後まで読んだ後では、何も心配する必要はありません。食べた後、皿の上の食べ物が1つ欠けていてはいけませんか?

要約すると
クロージャは、別の関数の変数を参照する関数であり、変数は参照されるため再利用されないため、プライベート変数をカプセル化するために使用できます。これは長所でもあり短所でもあります。不必要なクロージャはメモリ消費量を増やすだけです。 さらに、クロージャを使用する場合、変数は静的なプライベート変数に似ているため、変数の値が要件を満たしているかどうかにも注意する必要があります。クロージャは通常、さまざまな事柄と混同されていますが、ここでは基本的な事項について説明するためのほんの始まりにすぎません。

この記事へのリンク: http://www.cnblogs.com/qieguo/p/5457040.html

以上がこの記事の全内容です。皆様の学習のお役に立てれば幸いです。

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