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ページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答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 では、即時関数を使いましたが、
〇〇.△△()
と書きたいときに、 〇〇
が即時関数で得られた
オブジェクトでなければならないわけではないです。
たとえば、ご質問のコードでは、即時関数を使わずとも、
test
に sample
プロパティを持つオブジェクトを
そのまま代入して
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総合スコア9058
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/03/11 05:33
2018/03/11 09:15
2018/03/11 10:09
2018/03/12 13:10
2018/03/12 13:11
2018/03/14 05:15
2018/03/14 12:24