質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • jQuery

    8138questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

jqueryのこの記述のどこが間違っているでしょうか。

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 546

htmlファイルで以下のように書いたjsファイルを読んで、jsの中のreturnで戻した変数(=sample)の中に入っているいろいろな関数を実行したいです。

var test = (function () {
    // var sample = function() {
    //     console.log("a");
    // }

    return {
        sample: function () {
            console.log("a")
            var a = 1;
        }
    }
});

$(function () {
    $(window).load(function(){
        test.sample();
    });
    console.log("b");
});
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+6

こんにちは。

修正前:

 test.sample();

の、test の後に () を追加して

修正後:

  test().sample();

とすればよいかと思います。

修正前のtest.sample() だと、 test自体に sampleという関数型のプロパティがあって、
それを実行するという意図のコードになってしまいますが、sampleプロパティを持っているのは
testそのものではなくて、関数型であるtest を実行したときの返り値のオブジェクトですので、
test().sample() とすれば意図した動作になります。


追記1

もうひとつ、別の考え方の修正方法があります。

修正前:

var test = (function () {
    return {
        sample: function () {
            console.log("a")
            var a = 1;
        }
    }
});

上記では、 test に関数を代入していますが、これを、関数が返す値が
test に入るように修正します。
そのために、以下のように、最後の } の後に、 () を追加して

修正後:

var test = (function () {
    return {
        sample: function () {
            console.log("a")
            var a = 1;
        }
    }
}());


とするか、または、最後の ) の後に、 () を追加して

修正後:

var test = (function () {
    return {
        sample: function () {
            console.log("a")
            var a = 1;
        }
    }
})();

として、即時関数(IIFE: Immediately Invokable Function Expressions) にします。

こうすれば、 test が、関数型のsample プロパティを持つので、sample()
実行するために、test.sample() と書けます。


追記2

メソッドチェーン(←使い方が適切かわかりませんが)として「〇〇.△△();」と書きたい時には”〇〇”の部分は即時関数などを使って既に実行されている必要があると考えておけば大丈夫でしょうか。

とのことですが、考え方としては

〇〇.△△()
と書きたい時には、
〇〇 は△△というプロパティを持っていて、その△△が関数である必要がある。

ということを理解しておくとよいかと思います。

先の追記1 では、即時関数を使いましたが、
〇〇.△△()  と書きたいときに、 〇〇が即時関数で得られた
オブジェクトでなければならないわけではないです。
たとえば、ご質問のコードでは、即時関数を使わずとも、
test に sampleプロパティを持つオブジェクトを
そのまま代入して

var test =  {
    sample: function () {
        console.log("a")
         var a = 1;
    }
};

としておけば、

 test.sample();

と呼べます。

また、回答の初めに書いたほうの修正では、test を関数のままにしておいて、

var test =  function() {
    return { 
            sample: function () {
                console.log("a")
                var a = 1;
            }
    };
};

としておくならば

 test().sample();

とすればよいと書きましたが、このような、〇〇 が関数の呼び出しになっている場合も含めて、
より広く当てはまるように言い換えるならば、評価(evaluation) という言葉を使って、

〇〇.△△()
と書きたい時には、
〇〇 が評価された結果が、△△というプロパティを持っていて、
その△△が関数である必要がある。


ことを理解しておけばよいと思います。これであれば

test.sample()

test().sample()

のいずれの場合も説明がつきますし、さらに、ご質問のコードには無い例として

("hello" + " world").toUpperCase()

のように、○○が式になっていても、
“hello” + “ world” という式が評価された結果は “hello world” という
文字列で、文字列は toUpperCase() 関数を呼ぶことができて、
結果としては "HELLO WORLD" が得られることについても
矛盾しません。

ですので、

〇〇.△△()
と書きたい時には、
〇〇 が評価された結果が、△△というプロパティを持っていて、
その△△が関数である必要がある。

と覚えておく(というか、理解しておく)のが、様々なパターンを包含しているといえます。

この、「評価」あるいは「評価する」という用語は、 javascript に限らず、
プログラミングの基礎用語ですので、「javascript 式 評価」でググって、
分かりやすそうな記事を2,3読んでおかれるとよいかと思います。


追記3

追記2で提示した考え方を説明する最後の例では、 文字列 "hello world" が toUpperCase 
という関数型のプロパティを持っているかのように思われてしまうかもしれませんが、
実状は少し違っていて、"hello world" という文字列が、toUpperCase を持って
いるのはなく、 StringクラスのプロトタイプであるString.prototype 
が toUpperCase を持っていて、
"hello world".toUpperCase()
としたときは、この String.prototype の持っている toUpperCase() が呼ばれます。
ですので、この状況までも含めるならば、

〇〇.△△()
と書きたい時には、
〇〇 が評価された結果のオブジェクト、あるいは、そのオブジェクトの
(プロトタイプチェーン上にある、いずれかの)プロトタイプが △△という
プロパティを持っていて、その△△が関数である必要がある。

という言い方になるでしょう。


追記4

1. test と test() の違い

私が最初に書いた「test.sample()」は私は「test関数の中のsample関数を実行する」という意味だと思ってましたが、ここでの「test」は定義しただけの関数で実行されていないから、test.sample()と書いてもそもそも実行されていないtest関数の中のsample関数が実行されるわけがない、ということでしょうか。

はい。
そういう考え方で概ねよいと思います。
使いたいのは、test そのものではなくて、 test を実行したときに返されるオブジェクトの sample プロパティなので、test() というふうに () が必要ということですね

2. プロトタイプ

ちなみにプロトタイプというのはStringオブジェクトをDOMに変換した型?のことでしょうか。

いいえ、そうではありません。
プロトタイプとは何か?を説明すると長くなってしまうので、ここでは
私がJSの基本書として信頼している、
「徹底マスター JavaScriptの教科書」 第9章オブジェクト  9.1.2 プロトタイプ
からの引用に留めておきます。

— 引用ここから —

プロトタイプオブジェクト

JavaScript の関数は、関数オブジェクトであり、関数オブジェクトは標準で
prototype プロパティを持っています。

function F() {};

console.log(F.prototype);  // → Object {} 

関数のprototype プロパティが参照しているオブジェクトを、その関数の
プロトタイプオブジェクトといいます。
デフォルトでは、 prototypeプロパティは空のオブジェクトを参照しています。

プロトタイプオブジェクトのプロパティは、コンストラクタによって生成されたすべての
インスタンスから、あたかもそのインスタンスのプロパティであるかのように参照できます。

— 引用ここまで —

今現在、webstrerさんは、初学者とのことですので、学習を進めていったときに、
いずれ出てくると思いますので、現時点では、「そういうものがあるんだ」程度の理解で
大丈夫です。

3. 「評価」という概念について

プログラミング初学者の段階で、「評価」の厳密な定義を調べたり、覚えたりする必要はなく、
ごく直感的に、式を計算した結果とか、関数を実行した結果、ぐらいに思っておけば問題
ないです。

たとえば

1+1  を評価すると、2 です。

"Hello".toUpperCase() を評価すると “HELLO” です。

100 を評価すると、100 です。

みたいな感じです。

いろいろ脇道にそれたことをつけ加えた回答になり、
かえって混乱させてしまっていたら、すみません。

初学者のうちは、「これの考え方は、こうでいいのか?」という疑問が、いろいろ
出てくるとは思いますが、ある程度割り切って、
「今のところはこう考えておいて、あとでつじつまが合わないことが出てきたら、
そのときに考え方を修正しよう」
ということで進めていくことも、けっこう大事です。
その上で、どうしてもここは突っ込んで理解しておきたい、という疑問が出てくれば、
また、新たなご質問として投稿されるとよろしいかと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/11 14:33

    ありがとうございます!
    即時関数を調べてやっと理解できてきました。
    メソッドチェーン(←使い方が適切かわかりませんが)として「〇〇.△△();」と書きたい時には”〇〇”の部分は即時関数などを使って既に実行されている必要があると考えておけば大丈夫でしょうか。

    キャンセル

  • 2018/03/11 18:15

    > やっと理解できてきました。
    とのことでよかったです!

    > ・・・と考えておけば大丈夫でしょうか。
    について、追記2 で回答しましたので、参考になれば幸いです。

    キャンセル

  • 2018/03/11 19:09

    補足で、追記3 も書きました。
    いっぺんに理解しようとすると大変なので、
    ひとつひとつ順を追って、
    腰を据えて取り組まれるとよいでしょう。

    キャンセル

  • 2018/03/12 22:10

    大変詳しく説明してくださりありがとうございます。
    「評価」という概念は抽象的で初学者の私には理解しづらいのですが、評価はすべてのオブジェクトに対して行われ、評価の結果確定したオブジェクトの型に応じて、持つことのできるプロパティはあらかじめ決まっているということですよね?(StringオブジェクトだけがtoUpperCaseメソッドを持つことができるみたいな)
    ちなみにプロトタイプというのはStringオブジェクトをDOMに変換した型?のことでしょうか。つまりStringオブジェクトはDOM側ではString.prototypeと呼ばれるということなのでしょうか。
    ふと少し別のことを思ったのですが、私が最初に書いた「test.sample()」は私は「test関数の中のsample関数を実行する」という意味だと思ってましたが、ここでの「test」は定義しただけの関数で実行されていないから、test.sample()と書いてもそもそも実行されていないtest関数の中のsample関数が実行されるわけがない、ということでしょうか。
    そう考えたら即時関数を使う、またはtestをtest()に置き換えると無事にエラーにならずにsample()関数が実行された理由が説明できると思いました。

    キャンセル

  • 2018/03/12 22:11

    >ひとつひとつ順を追って、腰を据えて

    本当それですよね。
    普段は忙しくなかなかjsを本格的に勉強する時間が取れないです。

    キャンセル

  • 2018/03/14 14:15

    追記4 に回答しました。
    JSの学習がうまく進むことを願っております!

    キャンセル

  • 2018/03/14 21:24

    ありがとうございます。
    DOMは関係なかったんですね。
    まずコンストラクタがわからなかったのできつかったです。。
    そこから調べてみたいと思います。
    評価のところはかなりわかりやすくて助かりました。
    学習し始めのときほどあまりにもわからないことが多すぎて細かいところが気になってしまうというというのをこれまでも幾度となく経験してきましたが最初は細部はなかなか理解できないので現時点で支障がない限りはあまり気にせずわかるところを増やしていきたいと思います。
    大変詳細にご説明してくださり誠にありがとうございました。

    キャンセル

同じタグがついた質問を見る

  • jQuery

    8138questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。