0

私がこの質問をする主な理由は、時代遅れの JS 手法が役に立たなくなった、または単に時代遅れになっていると聞いたからです。'08 のスレッドを見ると、古い JS に関する否定的な意見をすべて聞いた後、恐怖を感じます。

私の主な関心事は、変数とファイルです。

ビデオ ゲーム用のある種の高度な計算機を作成したいので、グローバルにする必要がある変数がたくさんあります。ゲームのキャラクターには非常に多くの異なる「統計」があるため、より多くの書き込みを意味する場合でも、すべての前にプレフィックスを付けるだけで、次のようなことを行う方がよいでしょうか:

stats.health = 50;
stats.mana = 50;
stats.whatever = 100;

//or is this better:

health = 50;
mana = 50;
whatever = 100;

次の質問はファイルについてです。大量のデータ、ロードされた多数の画像、および画像用の多数の onTouch 関数を含むかなりの数の配列があります。それぞれに個別の JS ファイルを作成しますか? 最初にすべてのデータをロードし、次に画像、次に関数をロードし、一番下の /html または /body タグの前にリスナーを追加しますか? 私は以前から html + css を知っていましたが、Lua 出身ですが、JS を始めたばかりなので、アドバイスをいただければ幸いです。

よくわからないもう 1 つのことは、画像を作成する方法を少なくとも 3 つ見たことがありますが、それらの違いは何ですか?

例えば:

for (var i = 0; i < imageSrc.length; i++) {
image[i] = new Image(); 
image[i].src = "images/" + imageSrc[i] + ".png"; 
end

また:

document.createElement("img");

これは、ユーザーがページを使用している間に JavaScript を使用して画像を作成することです。

最初から存在するイメージを作成するより良い方法はありますか? たとえば、div 内でこれを作成します。

<img id="bgMain" src="images/background.png" style="position:absolute; top:0px; left:0px;" />

私の最後の質問は: http://jsperf.com/cached-vs-getelementbyid/5

キャッシュのパフォーマンスは明らかに優れていますが、 obj.elems.el が何であるか、または調べてもまったくわかりません。変数をキャッシュする方法について適切な説明へのリンクを持っている人はいますか?

また、より良いコーディング手法に関する追加情報やヒントも大歓迎です。読んでくれてありがとう、そして助けてくれてありがとう!

4

3 に答える 3

3

多くのグローバル変数を持つことについての良い議論は本当にありません。単一のグローバル コンテナーを作成し、その中にすべてを貼り付けます。

window.globalContainer = {};
globalContainer.var1 = 1;
globalContainer.var2 = 2;
//etc

エントリがイベントによって指示される範囲指定された環境ですべてを実行できるため、globalContainer を使用しなくても可能であることに気付くでしょう。

収容するすべてのファイルを.js取得する必要があります。フェッチは遅いので、複数回ではなく 1 回だけ実行するようにしてください。スクリプトをあちこちに配置するのではなく、すべてのスクリプトを 1 つのファイルに結合します。そうは言っても、それは本番環境でのみ行うべきです。開発するときは、最も読みやすいことを行う必要があります。本番用と開発用の JavaScript は常に異なる必要があることに注意してください。読みやすく論理的に分離されたものと、転送しやすく縮小されたもの。

画像をロードするためのルートは重要ではありません。createImageまたはnew Image()両方とも同じ結果になります。覚えておくべき重要なことは、実際の画像は.srcが割り当てられるまで取得されないということです。それが起こると、画像が読み込まれます。ブラウザがリソースを確認すると、それをキャッシュします。これが、プリロードの魔法がどのように起こるかです。レンダリングはまったく別の獣です。画像をキャッシュした場合でも、特に一度にレンダリングするように設定された多数の画像があり、それらが大きな画像である場合は、レンダリングに時間がかかる場合があります。

于 2013-05-28T23:07:05.160 に答える
2

以前のJSエクスプロイトに対する最大の議論は、大量のグローバル変数と衝突の可能性の増加でした...これを回避する最も簡単な方法は、歴史的にネームスペースでした...

//"this" is the global namespace, window in a browser.
this.project = this.project || {}; //establish project namespace
project.section = project.section || {}; // project.section
project.section.somevar = 0;
project.section.someMethod = function(){
  ...
};

これには長所と短所があり、長所は構造を取得し、衝突を回避できることです...短所は、このプラクティスでは、漏れやすい抽象化を最小限に抑えるために多くの規律が必要になることです。また、project.section.subsection.area.method のツリー検索のコストには、ルックアップ コストが少しかかります。

コード ファイルをすぐに呼び出される関数式 (IIFE) でラップすることにより、漏れやすい抽象化 (偶発的な変数のリーク) を減らすことができます。

(function(){
  this.project = this.project || {};
  //
}());

それでも、そのようなコードベースを維持するには、まだ多くの作業が必要です。最近では、JavaScript のモジュール パターンが増加しています。おそらく、モジュールの観点から考え、それらのモジュールとそれらが公開するオブジェクト/クラスを操作する必要があるでしょう。現在、これには Asynchronous Module Design (AMD) と CommonJS (CJS) の 2 つの一般的なパターンがあり、クライアント側で使用できるスクリプトにモジュールを構築するためのさまざまなツールもあります。

ほとんどの場合、 RequireJS (AMD) を使用し、Bower (JS Package Manager)、Grunt、およびYeomanを調べます。

これにはかなりの数のチュートリアルが用意されており、少なくとも構造の例については、FrozenJSのようなツールキットを調べることをお勧めします。

以下は、システムのモジュールを構築する方法の例です...上記のモジュールは、フィールドモジュールのエンティティから継承するフィールド上の特定のキャラクター用です...バインドを持つコンストラクター「キャラクター」を公開します( field) メソッド、および render() メソッド... 独自の状態を処理します。これは、キャラクター コントローラーまたは ViewModel (MVC/MVVM 用語で) と考えることができます。

//character.js AMD Module
define(['jQuery','./field'],function($,fieldModule){
  //module
  return {
    'Character':CharacterObject
    ...
  };

  function CharacterObject() {
    ... constructor internals ...
  }

  //inherit from field.Entity
  CharacterObject.prototype = new fieldModule.Entity();

  //prototype methods
  CharacterObject.prototype.bind = function(fieldInstance) {
    ... bind the CharacterObject instance to the field ...
  }

  CharacterObject.prototype.render = function() {
    ... render UI update(s) ...
    //assuming an event loop for UI processing
  }

  ...
});

これらすべてを超えて、価値のない仲介者の言語/コンパイル手順を犠牲にして、特定の動作の問題の可能性をさらに減らすコーヒースクリプトを検討することもできます.

于 2013-05-28T23:28:54.813 に答える
1

グローバルにする必要がある変数がたくさんあります

なぜ彼らはグローバルである必要があるのですか?データを見ると、キャラクターの統計計算を行っています。JavaScript で OOPを学び、オブジェクトに基づいてキャラクター モデルを構築することをお勧めします。そうすれば、それらは「文字のインスタンス」であり、グローバルではありません。私は次のようになります:

//build a character
var character = new Character('XXXfoozballXXX');
character.health = 100;
character.mana = 100;
character.simulateHit();
character.setStats({
  str:120,
  agi:120,
  luk:90,
  ...
});

//The data never lives in the global. They are in the instances of objects.
//You can discard them and build new ones without worry of globals or resetting

大量のデータ、ロードされた多数の画像、および画像用の多数の onTouch 関数を含むかなりの数の配列があります。それぞれに個別の JS ファイルを作成しますか?

依存関係を処理するフレームワークと構造が必要です。手始めにRequireJSBackboneを学ぶことをお勧めします。他にもフレームワークがありますが、それらはたまたま私が現在使用しているものです。

RequireJS では、モジュール性と再利用性のためにファイルを分割する必要がありますが、オプティマイザーでそれらを 1 つのファイルにコンパイルします。バックボーンは、データ、UI、およびロジックをオブジェクトに分割する方法も提供するため、最初に OOP を学ぶことが重要になります。

よくわからないもう 1 つのことは、画像を作成する方法を少なくとも 3 つ見たことがありますが、それらの違いは何ですか?

それを行うには多くの方法があります:

  • JavaScript で要素を構築する
  • JavaScript での Image オブジェクトの作成
  • HTML を作成して使用する.innerHTML()

私は 2 番目の方法を好みます。これは OOP に似ているため、他の OOP に似たコードで処理するのがはるかに簡単になるからです。

キャッシュのパフォーマンスは明らかに優れていますが、 obj.elems.el が何であるか、または調べてもまったくわかりません。変数をキャッシュする方法について適切な説明へのリンクを持っている人はいますか?

キャッシュされたメソッドが行ったことは、DOM から要素を 1 回だけ取得し、バインディングやフェッチなどではなく、テスト全体を割り当てに削減することでした。JavaScript と DOM は、いわば「別世界」です。ある「ランド」から別の「ランド」へのコードの交差には、オーバーヘッドが伴います。

そのオーバーヘッドを回避するには、「交差点」を制限します。すでに要素を 1 回フェッチしており、現在それを参照しているため、再度フェッチする必要はありません。代わりに、既存の参照を再利用してください。

于 2013-05-28T23:11:36.083 に答える