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

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

新規登録して質問してみよう
ただいま回答率
85.48%
jQuery

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

Q&A

解決済

1回答

1340閲覧

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

kantowebmanager

総合スコア29

jQuery

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

0グッド

1クリップ

投稿2018/03/11 00:52

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"); });

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

修正前:

javascript

1 test.sample();

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

修正後:

JavaScript

1 2 test().sample(); 3

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

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


追記1

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

修正前:

javascript

1var test = (function () { 2 return { 3 sample: function () { 4 console.log("a") 5 var a = 1; 6 } 7 } 8});

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

javascript

1var test = { 2 sample: function () { 3 console.log("a") 4 var a = 1; 5 } 6};

としておけば、

javascript

1 test.sample();

と呼べます。

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

javascript

1var test = function() { 2 return { 3 sample: function () { 4 console.log("a") 5 var a = 1; 6 } 7 }; 8};

としておくならば

javascript

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 01:02

編集2018/03/14 07:26
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kantowebmanager

2018/03/11 05:33

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

2018/03/11 09:15

> やっと理解できてきました。 とのことでよかったです! > ・・・と考えておけば大丈夫でしょうか。 について、追記2 で回答しましたので、参考になれば幸いです。
jun68ykt

2018/03/11 10:09

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

2018/03/12 13:10

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

2018/03/12 13:11

>ひとつひとつ順を追って、腰を据えて 本当それですよね。 普段は忙しくなかなかjsを本格的に勉強する時間が取れないです。
jun68ykt

2018/03/14 05:15

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

2018/03/14 12:24

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問