8

gameOfLive1)次のコードで、変数を作成する理由は何function gameOfLife()ですか?

2)とは何golですか?配列のように見えますが、構文やその呼び方に慣れていません。

私はhttp://sixfoottallrabbit.co.uk/gameoflife/を勉強しています

if (!window.gameOfLife) var gameOfLife = function() {

    var gol = {
        body: null,
        canvas: null,
        context: null,
        grids: [],
        mouseDown: false,
        interval: null,
        control: null,
        moving: -1,
        clickToGive: -1,
        table: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(''),
        tableBack: null,

        init: function(width, height) {
            gol.body = document.getElementsByTagName('body')[0];
            gol.canvas = document.createElement('canvas');
            if (gol.canvas.getContext) {
                gol.context = gol.canvas.getContext('2d');
                document.getElementById('content').appendChild(gol.canvas);
                gol.canvas.width = width;
                gol.canvas.height = height;
                gol.canvas.style.marginLeft = "8px";

                gol.control = document.getElementById('gridcontrol');

                gol.canvas.onmousedown = gol.onMouseDown;
                gol.canvas.onmousemove = gol.onMouseMove;
                gol.canvas.onmouseup = gol.onMouseUp;

                gol.addGrid(48,32,100,44,8);

                gol.refreshAll();
                gol.refreshGridSelect(-1);
                gol.getOptions(-1);

                gol.genTableBack();
            } else {
                alert("Canvas not supported by your browser. Why don't you try Firefox or Chrome? For now, you can have a hug. *hug*");
            }
        },
    }
}
4

7 に答える 7

15
var gameOfLife = function() { }

関数式ですが、

function gameOfLife() { }

関数宣言です。

関数式と関数宣言についてJuriy'kangax'Zaytsevを引用するには:

宣言と式の動作には微妙な違いがあります。

まず、関数宣言は、他の式よりも先に解析および評価されます。宣言がソースの最後に配置されている場合でも、スコープに含まれる他のすべての式が最初に評価され ます。[…]

関数宣言のもう1つの重要な特徴は、条件付きで宣言することは標準化されておらず、環境によって異なることです。条件付きで宣言されている関数に依存してはならず、代わりに関数式を使用してください。

この場合、Joel Coehoornがコメントで言及しているgameOfLifeように、条件付きで定義されているため、関数式を使用する必要があります。

これらの条件付きで定義された関数の一般的な使用例は、新しい関数(以前のECMAScript / JavaScriptバージョンでは使用できません)をネイティブでサポートしていないブラウザーでJavaScript機能を拡張することです。関数宣言を使用してこれを行うことは望ましくありません。関数宣言はとにかくネイティブ機能を上書きするためです。これは、(速度などを考慮して)必要な機能ではない可能性があります。この簡単な例

if (!Array.prototype.indexOf) { 
    Array.prototype.indexOf = function(item, from) {
        /* implement Array.indexOf functionality,
           but only if there's no native support */
    }
}

関数式の主な欠点の1つは、実際には無名関数を変数に割り当てることです。これにより、デバッグが困難になる可能性があります。これは、スクリプトの実行が停止したとき(たとえば、設定したブレークポイントで)、関数名が通常はわからないためです。Firebugなどの一部のJavaScriptデバッガーは、関数が割り当てられた変数の名前を指定しようとしますが、デバッガーはスクリプトの内容をオンザフライで解析してこれを推測する必要があるため、これは非常に難しい場合があります(結果として(?)()関数名の代わりに表示されている)または間違っていることさえあります。

(たとえば、その内容は初心者に完全に適しているわけではありませんが、ページを読んでください)

于 2010-07-09T00:18:07.847 に答える
15
  1. JavaScriptでは、関数はファーストクラスのオブジェクトです。それらをオブジェクト(変数)に格納し、引数として関数に渡すことができます。すべての関数は実際にはFunctionオブジェクトです。

  2. golはオブジェクトであり、オブジェクトリテラル表記を使用して初期化されています。

于 2010-07-08T21:49:10.987 に答える
4

1)次のコードで、gameOfLiveを単なる「関数gameOfLife()」ではなく変数にする理由は何ですか?


グローバルレベルで定義された変数は、ウィンドウオブジェクトのメンバーです。したがって、変数にすることで、構文を使用できるようになりますwindow.gameOfLife()。そのためif (!window.gameOfLife)、スニペットの先頭にあるチェックを使用できます。

しかし、それは彼らがこのようにそれを選択した理由を実際には説明していません、そして関数宣言は同じことをするでしょう。 Marcel Korpelの答えは、2つのオプションの「理由」をよりよく説明しています。


2)ゴルとは何ですか?配列のように見えますが、構文やその呼び方に慣れていません。


この構文は、コンパクトオブジェクト表記と呼ばれます。ここで興味深いのは、「コンパクト」オブジェクトが関数内で宣言されていることです。このような関数内でオブジェクトを宣言すると、(事実上)プライベートメンバーを使用してjavascriptオブジェクトを構築できるため便利です。

重要なのは、javascriptの関数とオブジェクトは同じものであることを覚えておくことです。したがって、完全なgameOfLife()関数は実際にはオブジェクト定義です。さらに、のgolメンバーとして宣言されたオブジェクトは、gameOfLifeプライベートメンバーを定義するための一般的な手法の一部である可能性があります。gameOfLife()関数/オブジェクトはこのオブジェクトを返しますgol。関数/オブジェクト内で宣言された他のすべてのアイテムはgameOfLife()、返されるgolインスタンスのプライベートメンバーになりますが、golオブジェクト自体の内部で宣言されたものはすべてパブリックです。彼らが本当にやりたいのは、最終的に次のようなコードを書くことです。

var game = new gameOfLife();

これを行うと、ゲーム変数はgolオブジェクトを保持します。このオブジェクトのメソッドは、完全なgameOfLife()関数で宣言されたアイテムに引き続きアクセスできますが、他のコードはアクセスできません(少なくとも、それほど簡単ではありません)。したがって、これらのアイテムは事実上プライベートです。golオブジェクト自体のアイテムはまだ公開されています。したがって、他のオブジェクト指向言語で構築するのと同じように、適切なカプセル化/情報隠蔽のためにプライベートメンバーとパブリックメンバーの両方を持つオブジェクトがあります。


于 2010-07-08T22:27:56.980 に答える
2

関数を変数に入れると、後でそれを別の関数に置き換えて、コードの残りの部分に対して透過的に関数を置き換えることができます。これは、フォームウィジェットで「onClick=」を指定するときに行うのと同じことです。

于 2010-07-08T21:51:17.290 に答える
1

確かに:構文を説明するには:

関数はJavaScriptのファーストクラスオブジェクトであるため、関数を変数に入れることができます。したがって、このコードの主要部分は、実際にはvar gameOfLifeに格納されている関数定義であり、後で次を呼び出すことで使用できます。

gameOfLife()

golはオブジェクト(ハッシュ)であり、「init」は上記の構文の別の例ですが、「gol」ハッシュの「init」キーに直接配置される点が異なります。そのため関数は次のように呼び出すことができます。

gol["init"](w,h)
于 2010-07-08T21:50:05.813 に答える
1

このページによると、彼らのやり方で宣言gameOfLifeすることは、あなたのやり方でそれを宣言することと何ら変わりはありません。彼らが定義golする方法はそれをオブジェクトにします(またはあなたはそれを連想配列と考えることができます)。配列の同様のショートカットは、中括弧の代わりに角括弧を使用することです。

于 2010-07-08T21:50:07.430 に答える
0

関数をオブジェクトのプロパティにしたい場合は、関数を変数と見なすと便利です。(http://www.permadi.com/tutorial/jsFunc/index.htmlを参照してください)

golは、JSON形式によく似た名前と値のペアで記述されたJavaScriptオブジェクトだと思います。(http://www.hunlock.com/blogs/Mastering_JSON_(_JavaScript_Object_Notation_)を参照してください)

于 2010-07-08T21:48:47.620 に答える