JavaScriptのクローズド、タイマー


閉包について話す
JavaScriptについては、ブロックスコープの概念はないが、関数スコープの概念があり、大域的環境から一つの関数内の局所変数にアクセスしたいなら、不可能である.しかし、JavaScriptのチェーン作用領域の概念によっては、外部のグローバル変数にアクセスできるので、関数内に定義されている関数に対しては、その親関数のすべての変数もアクセスできます.
クローズドクローズとは、内部関数が外部関数にアクセスできる変数です.一番簡単なクローズドクリ:
function Closure{
 var a = 1;//            a
 return function(){
   a = 2;   //  a  ,              a    
 }
}
func = Closure(); //             
func() //           ,  a       
クローズドの役割は、内部関数を外部変数にアクセスできるようにすることです.上記の例で示したように.クローズドのもう一つの役割は、いくつかの変数を常にメモリに保存することです.以下を見てください.
function func(){
 var a = 1;
 function add(){
   a++;
 }
 function ret(){
   return a;
 }
 return {
   ret:ret,
   add:add
 }
}
var f1 = func();
f1.add();
f1.add();
console.log(f1.ret());
はこのクリの中で、関数の中のサブ関数addは全部で2回運行しています.aの値を1から3に変更しました.父の関数は大域変数に割り当てられていますので、メモリに直接保存します.呼び出し後に自動的に消去されたのではありません.クローズドの使用に関する注意点は上記で述べたように、クローズドの特徴の一つであり、最も主要な特徴は、関数のすべての変数がメモリに保存されていることです.これらの変数ももちろんメモリを使っています.もしクローズドしすぎると、メモリに大きな負担をかけてしまい、性能問題を引き起こしたり、メモリが漏れたりする恐れがあります.ですから、クローズドを使用した後は必ず手動でこのメモリをクリアして、メモリの問題が現れないようにします.setTimeout 0はどのような役割を果たしていますか?字面上の意味から見れば、このような設定は関数を0 sの実行を遅延させることになりますが、そうではないです.関数を最後に実行させる役割を果たしています.例えば、setTimeout(function(){console.log(1);},0); (function(){console.log(12);}());以上の2つの関数の実行順序は順に1を印刷してから12を印刷するのではありません.前の関数に0 sの遅延が設定されているので、ここに実行すると巡回キューに入れられ、列の後進の原理に従い、他のコードを実行した後、列のコードを順次実行します.以下のコードの出力は何ですか?fnAr()出力iを修正し、2つ以上の方法で
 var fnArr = [];
 for (var i = 0; i < 10; i ++) {
     fnArr[i] =  function(){
         return i;
     };
 }
 console.log( fnArr[3]() );  // 10
を使用して1:
 var fnArr = [];
 for (var i = 0; i < 10; i ++) {
     fnArr[i] =  function(){
         return i;
     }(i);
 }
 console.log( fnArr[3] );  //
を修正します.2:
 for(var i=0;i<5;i++){
   (function(){
     var n = i;
     setTimeout(function(){
          console.log('delayer:' + n );
     }, 0);
   })();

     console.log(i);
 }
自動車の対象をカプセル化して、状態を取得します.
    var Car = carSet();
    function carSet(){
      var speed = 0;
      function setSpeed(spe){
        speed = spe;
      }
      function getSpeed(){
        console.log(speed);
        return speed;
      }
      function accelerate(){
        speed += 10;
      }
      function decelerate(){
        speed -= 10;
      }
      function getStatus(){
        if(speed === 0){
          console.log("stop");
          return "stop";
        }else{
          console.log("running");
          return "running";
        }
      }
      return{
        setSpeed:setSpeed,
        getSpeed:getSpeed,
        decelerate:decelerate,
        getStatus:getStatus,
        accelerate:accelerate
      }
    }
    Car.setSpeed(30);
    Car.getSpeed(); //30
    Car.accelerate();
    Car.getSpeed(); //40;
    Car.decelerate();
    Car.decelerate();
    Car.getSpeed(); //20
    Car.getStatus(); // 'running';
    Car.decelerate(); 
    Car.decelerate();
    Car.getStatus();  //'stop';
    //Car.speed;  //error
setTimeotを使ってsetIntervalをシミュレートする機能です.
    function getsec(){
      setTimeout(function(){
        console.log(new Date().getSeconds());
        getsec();
      },1000)
    }
setTimeoutの最小時間粒径を計算します.
    function cTime(){
      var i = 0;
      var sta = Date.now();
      var clo = setTimeout(function a(){
        i++;
        if(i === 1000){
          var end = Date.now();
          clearTimeout(clo);
          console.log((end - sta)/i);
        }
      clo = setTimeout(a,0);
      },0);
    }
    cTime();
下記コードの出力
//                   ,                 ,          :
var a = 1;
var a;
console.log(a);   // 1
a = 3;
console.log(a);  // 3
setTimeout(function(){
  a = 2;
  console.log(a);
},0)
以下のコードの出力
    var flag = true;
    setTimeout(function(){ //      ,          ,             
        flag = false;
    },0)
    while(flag){}  //       ,  flag    true,      ,     
    console.log(flag);
以上のコードはアナログコンソール上でtrueを出力しますが、実際にはダミーです.
以下の関数出力delayer: 0, delayer:1...は、クローズドパケットを使用して行われる.
for(var i=0;i<5;i++){
  (function(){
    var n = i;
    setTimeout(function(){
         console.log('delayer:' + n );
    }, 0);
  })();

    console.log(i);
}