Strings of Life

PHP/Phalcon/MySQL/JavaScript/RegExp/Ruby/Perl/ActionScript

タグ:ActionScript

再帰関数(recursive function)とは、自分自身を呼ぶ関数である。
function trouble () {
  trouble();
}
↑のように、関数内で自分自身を呼ぶことで繰り返し処理を行う。再帰関数について注意が必要なのは無限再帰である。trouble()は再帰の終了条件が設定されていないため、無限に自分自身を呼び出し続ける。再帰関数を書く際には、再帰の終了条件をあらかじめ設定しておくべきである。

再帰の古典的な例は、階乗計算である。
function factorial (n) {
  if (n < 0) {
    return; // 無効な入力なので終了
  } else if (n <= 1) {
    return 1;
  } else {
    return n * factorial(n-1);
  }
}

factorial(3) // 6
factrorial(5) // 120

もっとも、同じ処理はループを使うことでも実現できる。
function factorial (n) {
  if (n <0) {
    return;
  } else {
    var result = 1;
    for (var i = 1; i <= n; i++) {
      result = result * i;
    }
    return result;
}
再帰は複雑な問題を簡単な処理で解くことができる。しかし、関数を繰り返し呼び出すことは、ループに比べると処理の効率が悪いことが多い。また、Flashの実行環境は再帰の最大回数に制限を設けており、初期値では1000回までとなっている。


今日の進捗:2526→2553/20168(kindle用書籍フォーマット、mobi形式でのページ数)

多くのActionScriptのネイティブクラスと同様、Functionクラスのインスタンスもリテラル・シンタックスでつくることができる。関数リテラルは標準的な関数宣言と同様の文法だが、関数名は必要ない。
var square = function (n) {
return n * n;
}

square(5); // 25
関数リテラルは組み込み関数のflash.utils.setInterval()と一緒に使われることがある。次のような書き方をする:

setInterval(functionOrMethod, delay)

setInterval()関数はインターバル(一定時間ごとに動作する機能)を設定し、自動的に関数又はメソッドをdelayミリ秒ごとに実行する。インターバルが設定されると、interval IDとなる数字が設定され、setInterval()から返る。Interval IDは変数に代入できる。したがって、後からそのタイマーをclearInterval()によって停止することができる。


今日の進捗:208→211/1644

☆関数からのアクセス定義

プログラム内での関数の配置によって、プログラム中で定義されているもの(クラス、変数、メソッド、名前空間、インターフェース、他の関数)へアクセスできるかどうかが決まる。

しかし、関数がどこで定義されていようと、関数クロージャーの中で、thisキーワードは常にグローバルオブジェクトを参照する。インスタンスメソッドの中でネストされた関数を用いて現在のオブジェクトにアクセスする際には、thisを変数に代入すればよい。

例:
public function m () {
    var currentObject = this;

    function f () {
        // ここでもcurrentObjectにはアクセスできる
        trace(currentObject);
    }
}

☆値としての関数

ActionScriptでは、全ての関数はFunctionクラスのインスタンスである。したがって、関数は、その他の値と同様、変数へ代入したり、関数の戻り値にしたりできる。

例:
function a () {
}
var b = a;
// var b = a(); ではない
ここでは、関数a()を定義した後で、a()を変数bに代入している。注意が必要なのは、括弧演算子が無いことである。もし括弧演算子が含まれていれば、bにa()を代入するのではなく、a()の戻り値を代入することになる。

関数を変数に代入した後は、括弧演算子を使って関数を呼び出すことができる。

例:
b(); // a()と同じ結果が返る

今日の進捗:206→207/1644

関数定義がソースファイルの最上位で行われていて、package本文の外側にある場合、そのソースファイルに限って利用可能な関数が作成される。

例:

A.as
package {
  class A {
    public function A () {
    }
  }
}

function f () { }
関数f()は、上記のコードのどこからでも呼び出せる。注意が必要なのは、ソースファイルレベルの関数定義には、アクセスコントロール修飾子を含めてはならない、ということである。

ソースファイルレベル関数は単独のクラスを補助するために用いられることがある。しかし、privateな静的メソッドもクラスを補助する働きをするため、ソースファイルレベルの関数は実際のActionScriptプログラムではめったに見かけない。


今日の進捗:204→205/1644

関数がメソッドの内部や別の関数の内部で定義されている場合、その関数を含むメソッド又は関数の内部でのみ使用出来るネストされた関数(nested function)を作ることになる。

ネストされた関数は、それを含んでいるメソッド又は関数で限定的に利用されるタスクを実行する関数として作られる。

ネストされた関数は、その関数を含んでいるメソッド又は関数の内部でのみ呼ぶことができ、外部からは呼び出せない。
// メソッドa()を定義
public function a () {
    // ネストされた関数b()を呼ぶ
    b();

    // ネストされた関数b()を定義
    function b () {
        //関数の本文
    }
}

今日の進捗:202→203/1644

このページのトップヘ