62832


お世話になります。  
GASでWebアプリケーションを作成し、パラメーターをオブジェクトに格納してから、同じ値を持っている2つの要素を`!=`または`!==`で比較すると、真が返ってしまうという現象に悩まされています。  
自分なりに簡単にまとめたコードは以下のようになります。

[code]

    function doGet (e) {
      var parm = e.parameters;
      var foo = {};
      for (var key in parm) {
        foo[key] = parm[key];
      }
      Logger.log('foo.x:【' + foo.x + '】');
      Logger.log('foo.y:【' + foo.y + '】');
      Logger.log('x != y:' + (foo.x != foo.y));
      Logger.log('x !== y:' + (foo.x !== foo.y));
    }
    
[/code]

上のコードをWebアプリケーションとしてデプロイし、以下のURLにアクセスします。

>
> [https://script.google.com/a/組織名.example.com/macros/s/](https://script.google.com/a/%E7%B5%84%E7%B9%94%E5%90%8D.example.com/macros/s/){オブジェクトID}/exec?x=A&y=A

doGet()はHTMLを返していませんので、ブラウザーには以下のメッセージが表示されます。

> The script completed but did not return anything.

そして、スクリプトエディタでCtrl+Enterを押下してログを表示すると以下のようになります。

> [20-02-05 03:14:34:357 PST] foo.x:【A】  
>  [20-02-05 03:14:34:357 PST] foo.y:【A】  
>  [20-02-05 03:14:34:358 PST] x != y:true  
>  [20-02-05 03:14:34:359 PST] x !== y:true

`foo.x`も`foo.Y`もAという値を格納しているのに、なぜ`!=`および`!==`が真になるのでしょうか。  
よろしくお願いいたします。


CC BY-SA 4.0
2020-02-05T11:24:42.103
62808
2020-02-06T13:19:37.657
2020-02-05T12:50:17.603
19110
26673
question
javascript html google-apps-script
GASでパラメータをオブジェクトの値にすると!=がおかしくなる？


コメントをいただき、ありがとうございます。  
自己回答の形でまとめさせていただきます。  
質問のコードを以下のように改めて実行しました。

[code]

    function doGet (e) {
      var parm = e.parameters;
      var foo = {};
      foo.v = 'B';
      foo.w = 'B';
      for (var key in parm) {
        foo[key] = parm[key];
      }
      for (var key in foo) {
        Logger.log('foo[' + key + ']:' + foo[key] + ' typeof(foo[key]):' + typeof(foo[key]));
      }
      Logger.log('foo.v:【' + foo.v + '】');
      Logger.log('foo.w:【' + foo.w + '】');
      Logger.log('foo.x:【' + foo.x + '】');
      Logger.log('foo.y:【' + foo.y + '】');
      Logger.log('v != w:' + (foo.v != foo.w));
      Logger.log('v !== w:' + (foo.v !== foo.w));
      Logger.log('x != y:' + (foo.x != foo.y));
      Logger.log('x !== y:' + (foo.x !== foo.y));
    }
    
[/code]

結果は以下のとおりです。

> [20-02-06 00:49:30:187 PST] foo[v]:B typeof(foo[key]):string [20-02-06  
>  00:49:30:189 PST] foo[w]:B typeof(foo[key]):string [20-02-06  
>  00:49:30:189 PST] foo[x]:A typeof(foo[key]):object [20-02-06  
>  00:49:30:190 PST] foo[y]:A typeof(foo[key]):object [20-02-06  
>  00:49:30:191 PST] foo.v:【B】 [20-02-06 00:49:30:191 PST] foo.w:【B】  
>  [20-02-06 00:49:30:192 PST] foo.x:【A】 [20-02-06 00:49:30:192 PST]  
>  foo.y:【A】 [20-02-06 00:49:30:193 PST] v != w:false [20-02-06  
>  00:49:30:193 PST] v !== w:false [20-02-06 00:49:30:194 PST] x !=  
>  y:true [20-02-06 00:49:30:195 PST] x !== y:true

以上のことから以下のことが分かりました。

  * `foo[key] = 'STR'`という代入によって得られる`foo[key]`は文字列で値は`STR`
  * WebAppを`?key=STR`というクエリーパラメーターとともに呼び出し、`doGet(e)`関数で受けて、`foo[key] = e.parameters[key]`という代入によって得られる`foo[key]`は配列で中身は`["STR"]`
  * `foo[key_1] = 'STR_1'`、`foo[key_2] = 'STR_2'`を実行した場合`foo[key_1] != foo[key_2]`は`true`
  * `foo[key_1] = ['STR_1']`で`foo[key_2] = ['STR_2']`の場合`foo[key_1] != foo[key_2]`は`false`

いっぽう、上記のコードの

[code]

      var parm = e.parameters;
    
[/code]

を

[code]

      var parm = e.parameters;
    
[/code]

と変更して実行すると、以下の結果が得られました。

> [20-02-06 01:01:52:327 PST] foo[v]:B typeof(foo[key]):string [20-02-06  
>  01:01:52:327 PST] foo[w]:B typeof(foo[key]):string [20-02-06  
>  01:01:52:328 PST] foo[x]:A typeof(foo[key]):string [20-02-06  
>  01:01:52:329 PST] foo[y]:A typeof(foo[key]):string [20-02-06  
>  01:01:52:329 PST] foo.v:【B】 [20-02-06 01:01:52:330 PST] foo.w:【B】  
>  [20-02-06 01:01:52:331 PST] foo.x:【A】 [20-02-06 01:01:52:331 PST]  
>  foo.y:【A】 [20-02-06 01:01:52:332 PST] v != w:false [20-02-06  
>  01:01:52:333 PST] v !== w:false [20-02-06 01:01:52:333 PST] x !=  
>  y:false [20-02-06 01:01:52:334 PST] x !== y:false

以上のことから、以下のことが分かりました。

  * WebAppをクエリーパラメーター`?key=STR`とともに呼び出し、`doGet(e)`関数で受けて、`foo[key] = e.parameter[key]`という代入によって得られる`foo[key]`は文字列で中身は`"STR"`

要約すると、

  * doGet(e)においてe.parametersは各クエリーパラメーターを配列で返す
  * おなじくdoGet(e)においてe.parameterは各クエリーパラメーターを文字列で返す

<https://developers.google.com/apps-script/guides/web>

  * JavaScriptは同じ値を持つ2つの異なるオブジェクトを比較すると、!=も!==も常にtrueになる

<https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Comparison_Operators>

クエリーパラメーターを複数得たいケースが現在開発中のシステムには存在しないので、`e.parameter()`を使用することで対応できそうです。

コメントありがとうございました！！


CC BY-SA 4.0
2020-02-06T09:15:33.547
62832
2020-02-06T13:19:37.657
2020-02-06T13:19:37.657
26673
26673
62808
answer