JavaScriptのクローズド、タイマー
15819 ワード
閉包について話す
JavaScriptについては、ブロックスコープの概念はないが、関数スコープの概念があり、大域的環境から一つの関数内の局所変数にアクセスしたいなら、不可能である.しかし、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);
}