

**「関数内で定義したグローバルオブジェクト」を引数として渡しているコードがあったのですが、どういった理由が考えられるでしょうか？**  
・「window」や「this」でもないのになぜ？？  
・基本的には「グローバルオブジェクト」は引数として渡す必要はない、という認識で合っているでしょうか？  
・「グローバルオブジェクト」を引数として渡さなければいけない(あるいは渡した方が良い)のは、例えばどんな時ですか？  
・複数ファイルに跨っている時？？

[code]

    function f1() {
      obj = {
        p: "値"
      }
      f2(obj);
    }
    
[/code]


CC BY-SA 3.0
2017-05-30T00:17:30.737
35117
2017-05-30T08:24:44.017
7886
question
javascript
「関数内で定義したグローバルオブジェクト」を引数として渡している理由として、考えられることは？


蛇足かもしれませんが、混乱を招くこともある話ですので、用語についてまず確認しておきます。

## 1\. グローバルオブジェクト

**一般に** 、JavaScriptでいうところのグローバルオブジェクトとは、言語仕様（ECMAScript）でいうところの[ _Global
Object_](https://tc39.github.io/ecma262/#sec-global-
object)、すなわち言語システムで最も広い変数スコープに相当する、ある **唯一** のオブジェクトを指します。このオブジェクトの実装それ自体は
_implementation-dependent（実装依存）_
とされていますので、処理系ごとに振る舞いが違います。たとえばブラウザであれば`window`、nodeなどであれば`global`という名前でアクセスできるオブジェクトとして実装されていますね。いずれにしても、スコープがグローバルであるという意味は、普通の理解のとおり
**どこからでもアクセスできる** ということです。たしかにwindowなどはどこからでもアクセスできます。

## 2\. グローバルなオブジェクト

対して質問にある「グローバルオブジェクト」というのは、あえて言うならば **グローバルなオブジェクト**
、グローバルスコープにあるオブジェクト、あるいは他言語において同義語を拾えば **グローバル（大域）変数** にあたります。これは前項のGlobal
Objectのプロパティとして定義されるため、Global Objectと同じスコープ、つまり **どこからでもアクセスできる変数**
、グローバル変数のことです。そういう意味で「グローバルオブジェクト」と呼称する文脈もあります。

## 関数にグローバルオブジェクトを渡す……？

前述のとおりグローバルオブジェクトおよびグローバルなオブジェクトはどこからでもアクセスできるスコープに定義されたオブジェクトです。これを関数に渡すことについて、結局参照できるんだから

> 「グローバルオブジェクト」は引数として渡す必要はない

という見方も可能ではあります。しかしながら、たとえばjQueryなんかをつかったことがありましたら、グローバルオブジェクト、あるいはグローバルなオブジェクトを関数に渡す
**意味** を、すくなくとも体感しているはずです。

[code]

    // $ = jQuery: 関数
    
    // windowオブジェクト（グローバルオブジェクト）に
    // 対するjQueryオブジェクトを生成
    const $window = $(window);
    
    // documentオブジェクト（グローバルなオブジェクト;window.document）に
    // 対するjQueryオブジェクトを生成
    const $document = $(document).ready(...)
    
[/code]

このように、関数にグローバルオブジェクトあるいはグローバルなオブジェクトを渡す動作は特別でも珍しくも不自然でもありません。

> ・「グローバルオブジェクト」を引数として渡さなければいけない(あるいは渡した方が良い)のは、例えばどんな時ですか？  
>  ・複数ファイルに跨っている時？？

渡さなければならない、というのはすこし不自然な言い方ですが、たとえばライブラリの実装でクロージャを使って書かれるときならば、当然ながら「外部からライブラリを使用できるようにするため」にはグローバルオブジェクトまたはグローバルなオブジェクトを参照しておく必要があります。あまりいい例ではないかもしれないです。

[code]

    // ライブラリ実装をクロージャにとじこめる
    (function (root) {
        // ローカル変数はローカルスコープにかくす
        const privateObject = {
            publicProperty: 0,
        };
    
        // ライブラリ関数のエクスポート
        root.library = {
            getPublicProperty: () => privateObject.publicProperty,
        };
    })(this);
    // エクスポート先となるオブジェクトは、どこからでも参照できるように
    // グローバルオブジェクトまたはグローバルなオブジェクト
    
[/code]

実際になにかを実装していくときに、それがグローバルオブジェクトであるか、グローバルスコープにあるものであるか、というのはほとんど気にする必要はないかと思います（私は気にして設計したことはたぶんありません）。他方、すくなくともpureなjsはduck-
typingな型付けを採用していますので、 **渡されたオブジェクトが適切であるかを検証する**
ほうがより実質的に重要です。あるいは渡す側でいうならば、Global
Objectが渡されることを予期していない処理（たとえばオブジェクトに破壊的な操作を行う拡張メソッド）に渡さないようする、程度でしょうか。

以上、直接の回答にはなっていませんので参考程度にお願いいたします。


CC BY-SA 3.0
2017-05-30T08:24:44.017
35128
2017-05-30T08:24:44.017
35117
answer