22

GSファイルの実行順序ルールに関するドキュメントはどこで読むことができますか?

問題の次元を決めるために、それぞれ独自のファイルに2つの些細なオブジェクトを作成しました。

1_File.gs

var ObjB = new Object();
ObjB.sayName = "[" + ObjA.sayName + "]";

0_File.gs

var ObjA = new Object();
ObjA.sayName = " I'm A ";

...などの呼び出し

Logger.log(ObjA.sayName + " : " + ObjB.sayName);

...エラーが発生します...

TypeError: Cannot read property "sayName" from undefined.

コードを1_File.gsから0_File.gsに、またはその逆に移動した場合、エラーは発生せず、ログは正しく表示されます...

私はAです:[私はAです]

0_File.gsの名前を2_File.gsに変更しても実行順序には影響しないため、順序は最初に作成されるファイルによって異なると思います。

実行の順序を明示的にすることができる「インクルード」または「インポート」の概念はありませんか?

4

7 に答える 7

12

GSファイルの実行順序ルールに関するドキュメントはどこで読むことができますか?

そのようなドキュメントはなく、いつでも公開されることはないと思います。同様に、C ++での静的変数の初期化順序も未定義であり、コンパイラー/リンカーに依存します。

実行の順序を明示的にすることができる「インクルード」または「インポート」の概念はありませんか?

はい、「インクルード」、「インポート」、さらには「モジュール」はありませんが、ライブラリはあります。

また、クロージャーを使用することによる回避策があります。以下はサンプルコードです。テスト機能を実行すると、ログにが含まれますc.d。アイデアは、すべてのgsファイルに。で始まる関数を含めることinitです。これらの関数では、すべてのグローバル変数がインスタンス化されます。匿名クロージャはファイルのインスタンス化中に実行され、すべてのファイルCode.gsのすべての「init」関数を呼び出しgsます。

Code.gs

var c;

function callAllInits_() {
  var keys = Object.keys(this);
  for (var i = 0; i < keys.length; i++) {
    var funcName = keys[i];
    if (funcName.indexOf("init") == 0) {
      this[funcName].call(this);
    }
  }
}

(function() {
  callAllInits_();
  c = { value : 'c.' + d.value };
})();

function test() {
  Logger.log(c.value);
}

d.gs

var d;

function initD() {
  d = { value : 'd' };
};
于 2012-10-02T17:25:59.727 に答える
3

各ファイルにクラスを作成し、各クラスが元のファイルCode.gs(名前を変更した_init.gs)でインスタンス化されていることを確認することで、この問題に取り組みました。各クラスのインスタンス化は、の形式として機能し、include何かを実行する前にすべてが適切に配置されていることを確認します。

_init.gs

// These instances can now be referred to in all other files
var Abc  = new _Abc();
var Menu = new _Menu();
var Xyz  = new _Xyz();
var Etc  = new _Etc();

// We need the global context (this) in order to dynamically add functions to it
Menu.createGlobalFunctions(this);

function onInstall(e) {
  onOpen(e);
}

function onOpen(e) {
  Menu.build();
}

そして、クラスは通常次のようになります。

menu.gs

function _Menu() {
  this.build = function() {
    ...
  }

  ...
}
于 2015-11-03T19:55:51.463 に答える
2

複数のレベルの継承がある場合は、実行する前に、init関数に、、、、などの名前を付けてから、名前でinit関数を並べ替える必要がinit000Fooありinit010Barますinit020Baz。これによりinit000Foo、最初に評価され、次にBar、次に評価されるようになりBazます。

function callAllInits() {
  var keys = Object.keys(this);
  var inits = new Array();
  for (var i = 0; i < keys.length; i += 1) {
    var funcName = keys[i];
    if (funcName.indexOf("init") == 0) {
      inits.push(funcName);
    }
  }

  inits.sort();
  for (var i = 0; i < inits.length; i += 1) {
    // To see init order:
    // Logger.log("Initializing " + inits[i]);
    this[inits[i]].call(this);
  }
}
于 2018-03-26T06:56:52.193 に答える
1

他の回答(つまり、他のファイルのオブジェクトを参照するトップレベルのコードを記述しない)は、この問題を回避するための理想的な方法を説明しています。ただし、すでに多くのコードを記述していて、それを書き直すことが不可能な場合は、回避策があります。

Google App Scriptは、作成された順序でコードファイルをロードしているように見えます。最初に最も古いファイル、次に次のファイル、最後に最後に作成されたファイル。これは、[ファイルをアルファベット順に並べ替える]がオフになっている場合にエディターに表示される順序です。

したがって、この順序でファイルがある場合:

  • Code.gs
  • 1_File.gs(0_File.gsに依存)
  • 0_File.gs

簡単な修正方法は、1_File.gsのコピーを作成してから元のファイルを削除し、リストの最後に効果的に移動することです。

  1. 1_File.gsの横にある三角形をクリックし、[コピーを作成]を選択します
    • Code.gs
    • 1_File.gs
    • 0_File.gs
    • 1_ファイルcopy.gs
  2. 1_File.gsの横にある三角形をクリックし、[削除]を選択します
    • Code.gs
    • 0_File.gs
    • 1_ファイルcopy.gs
  3. 1_File copy.gsの横にある三角形をクリックし、[名前の変更]を選択して、最後から「コピー」を削除します。
    • Code.gs
    • 0_File.gs
    • 1_File.gs

これで、0_File.gsが1_File.gsの前にロードされます。

于 2018-01-03T02:40:51.570 に答える
0

これは2021年12月の時点で私にとってはうまくいきます。おそらく、他の答えは時代遅れです。

これは簡単に修正できます。Webエディタの[ファイル]セクションにあるスクリプトを見ると、順序があることがわかります。ファイルは、そこに表示される順序で評価されます。ファイル名の右側にある3つのドットをクリックすると、ファイルを上下に移動できるメニューが表示されます。

于 2021-12-06T07:48:07.703 に答える
-1

GoogleAppsScriptにはそのような順序はありません。これは、これらのオブジェクトをどこで宣言するか、および関数がどのように呼び出されるかに完全に依存します。Logger.log()コードがいつどのように呼び出されるかについて少し説明してください。また、オブジェクトobjAとobjBをいつ宣言しますか?これらは私たちがより良い答えを提供するのに役立ちます

于 2012-10-02T16:19:27.280 に答える
-2

これが私がこれを行う方法です...

主要

function include(filename) {
  return ContentService.createTextOutput(filename);
}

function main() {
  include('Obj A');
  include('Obj B');
  Logger.log(ObjA.sayName + " : " + ObjB.sayName);
}

Obj A

var ObjA = new Object();
ObjA.sayName = " I'm A ";

Obj B

var ObjB = new Object();
ObjB.sayName = "[" + ObjA.sayName + "]";
于 2014-02-06T21:35:41.393 に答える