ちょっと変わったカウンタの作り方
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ JavaScriptで自分自身を書き換える関数を使います
JavaScriptで実行するたびに数値が増えていく関数を作ろうとするとclosureを使うと思います
もっと便利なカウンタを作る関数自体を作っておく方法↓もありますが今回は置いておきます
JavaScriptは無名関数の代入で関数を作ると上から順番に実行してその行を実行して初めて関数が作られます
当たり前のようですがfunction構文とvarによるローカル変数生成はスコープの一番最初にまとめて行われます
なので
xは最初に定義されてしまうので実行できてますが yはy()の実行後に定義されるのでエラーになります
x関数の中のconsole.log(t)は10になりそうなものですが スコープ内のvarはスコープの最初にundefinedで初期化されるのでt=100をする前はundefined その後でtに値を代入してからは100が表示されています
最後のcounter()は単純に直前で上書きしたcounter関数を実行しています
2回目以降のcounter関数の実行時には元々のcounterは消えていますがclosureとしてcountのスコープは残っているのでインクリメントさせることでカウンタとして動かせます
普通に作ると
だいたいこんなものですよねvar counter = function(){
var count = 1;
return function(){
console.log(count++);
}
}()
counter() // 1
counter() // 2
counter() // 3
もっと便利なカウンタを作る関数自体を作っておく方法↓もありますが今回は置いておきます
var counter_generator = function(start){
var count = start;
return function(){
console.log(count++);
}
}
function構文でしたい
この書き方だと無名関数を代入することになりますJavaScriptは無名関数の代入で関数を作ると上から順番に実行してその行を実行して初めて関数が作られます
当たり前のようですがfunction構文とvarによるローカル変数生成はスコープの一番最初にまとめて行われます
なので
t = 10
x()
y() // エラー
function x(){
console.log("function x")
console.log(t) // ローカルにtが作られているからグローバルのtは見れない
var t = 100
console.log(t) // ↑の代入結果
}
y = function(){
console.log("function y")
}
結果function x
undefined
100
Uncaught ReferenceError: y is not defined
undefined
100
Uncaught ReferenceError: y is not defined
xは最初に定義されてしまうので実行できてますが yはy()の実行後に定義されるのでエラーになります
x関数の中のconsole.log(t)は10になりそうなものですが スコープ内のvarはスコープの最初にundefinedで初期化されるのでt=100をする前はundefined その後でtに値を代入してからは100が表示されています
やり方
function counter(){
var count = 1
counter = function(){console.log(count++)}
counter() // 再帰してるわけじゃない
}
counter() // 1
counter() // 2
counter() // 3
関数内で自分自身を書き換えます最後のcounter()は単純に直前で上書きしたcounter関数を実行しています
2回目以降のcounter関数の実行時には元々のcounterは消えていますがclosureとしてcountのスコープは残っているのでインクリメントさせることでカウンタとして動かせます