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

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

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

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

4回答

5030閲覧

javascriptで複数の処理があるような場合すべてを一塊で即時関数で囲みますか?

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2017/08/04 05:06

javascriptで複数の処理があるような場合すべてを一塊で即時関数で囲みますか?
それともtaxNum、calcNumのようにCSSのBEMのようなことをして即時関数で囲まなくても被らないようにしますか?

すべての式の塊をとりあえず即時関数で囲んでしまえば被る心配がないので、長い名前にしなくても良いですが、今度はスコープの問題で、参照できない事にはまる危険性があり、プロはどちらを選ぶのか気になります。

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

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

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

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

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

guest

回答4

0

objectをnamespaceのように使うこともできます。

javascript

1const hoge = { 2 foo: function() {}, 3 bar: function() {}, 4 baz: function() {} 5} 6 7const fuga = { 8 foo: function() {}, 9 bar: function() {}, 10 baz: function() {} 11}

投稿2017/08/04 06:59

YukiYonekura

総合スコア127

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

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

退会済みユーザー

退会済みユーザー

2017/08/04 07:12

即時関数でやる方法がすべてと思っていましたが、オブジェクトで囲んでもカプセル化出来るということですね。 即時関数との違いは変数名だけカプセル化でき、外から参照出来ない関数スコープはできないという事でしょうか?
退会済みユーザー

退会済みユーザー

2017/08/04 07:14

すると同じ名前の変数がオブジェクトの中にあった場合は、別物のなるのですね。
so87

2017/08/08 02:35 編集

そうですね。その考え方でOKです。 私の場合は、YukiYonekuraさんの回答のように関数定義はオブジェクトやクラスの中に入れる事が多いです。 テストコードで呼び出せるようにアクセス手段を持たせてます。 ロジックを含めた代入操作は即時関数でカプセル化してます。 Javascriptはブロックスコープがないためです。
so87

2017/08/08 04:04

そうでした!Babel使ってない案件もあり、つい古い考え方でコメントしてしまいました。 訂正ありがとうございます。
退会済みユーザー

退会済みユーザー

2017/08/08 05:51

確かにletを使うと同じ変数名は使えなくなるので変数名のカプセル化は即時関数で囲む必要が6から無くなったということでしょうか? ただそれでもBEMのように被らない長い名前をつけないといけないけないことは変わりませんよね。 即時関数であればResultなどよく使うものも何度も使えますが。
guest

0

ベストアンサー

外部スコープに公開する必要性

例えば

計算1

計算2

計算3
と会った場合三つをそれぞれ即時関数で囲んでカプセル化するかどうかです。
そうしないと名前が被る問題がありますよね。

「計算1」「計算2」「計算3」を外部スコープに公開する必要があるならグローバル関数化します。

JavaScript

1function calc1 () {} 2function calc2 () {} 3function calc3 () {} 4 5// 外部スコープから関数呼び出しされるので、グローバル関数化しなければならない。 6calc1(); 7calc2(); 8calc3();

外部スコープに公開する必要がないのなら即時関数で括ります。

JavaScript

1(function () { 2 function calc1 () {} 3 calc1(); 4}()); 5 6(function () { 7 function calc2 () {} 8 calc2(); 9}()); 10 11(function () { 12 function calc3 () {} 13 calc3(); 14}());

calc1, calc2, calc3 間でのみスコープを共有できれば良いのであれば、まとめて即時関数で括ります。

JavaScript

1(function () { 2 function calc1 () {} 3 function calc2 () {} 4 function calc3 () {} 5 6 calc1(calc2(calc3())); 7}());

まとめ

結局、バランスの問題なので一概にどちらが良いといえるものではないと思います。

すべての式の塊をとりあえず即時関数で囲んでしまえば被る心配がないので、長い名前にしなくても良いですが、今度はスコープの問題で、参照できない事にはまる危険性があり、プロはどちらを選ぶのか気になります。

「即時関数で括る事でスコープ範囲外になってしまう」のは設計の問題であって、即時関数で括る事が問題なのではありません。
関数スコープ/ブロックスコープを利用して出来るだけ変数のスコープを狭くしつつ、各々のスコープ内に収まるコードにするのが基本になります。

投稿2017/08/04 06:57

think49

総合スコア18164

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

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

退会済みユーザー

退会済みユーザー

2017/08/04 07:41

>>> (function () { function calc1 () {} calc1(); }()); (function () { function calc2 () {} calc2(); }()); (function () { function calc3 () {} calc3(); }()); やはり、即時関数で処理の塊を囲んで変数名が被っても別物にするというのは、 一般的に行われているのですね。 すべてこのようにすれば、一番外側にそのファイル内の処理すべてを囲む即時関数は不要になるのですね。
think49

2017/08/04 07:50

「処理の単位」を1つにするか3つに分けるかは一概にいえるものではありませんので、「設計次第」という点は補足しておきます。 amebatv さんが出した例示「計算1、計算2、計算3」にはそれを判断できる要素はありませんので、私としてはどちらが良いともいえません。
退会済みユーザー

退会済みユーザー

2017/08/04 09:24

>>> // 外部スコープから関数呼び出しされるので、グローバル関数化しなければならない。 calc1(); calc2(); calc3(); グローバル関数とは初めて聞いたのですが、グローバルに宣言した関数のことなのでしょうか? グローバル変数と同じようなものですか? 上記の例では定義はグローバルではなく即時関数内で行い、呼び出しだけをグローバルで行う事によって、呼び出しがグローバルなだけでグローバル関数という形になるという事でよいでしょうか?
think49

2017/08/04 12:31 編集

グローバル関数は「グローバルスコープ上に存在する関数」の事です。 グローバルコード上で定義された関数はグローバル関数です。 その例でいえば、正確には必ずしもグローバルスコープである必要はなくて、即時関数で括った場合に外側のスコープから calc1, calc2, calc3 を参照できなくなり、calc1(); が ReferenceError になる状況を表しています。 解決するには、3つ目のコードのように限定的にスコープを共有するか、1つ目のようにグローバルスコープまで開放する必要があります。
退会済みユーザー

退会済みユーザー

2017/08/15 02:28

(function () { function calc1 () {} function calc2 () {} function calc3 () {} calc1(calc2(calc3())); }()); このように三つの関数を同じ即時関数内に入れるか、 即時関数が外のグローバルスコープ(始めから作成されているどこからでも参照できるスコープ) に関数を定義すれば良いという事ですね。
guest

0

let const を使えば再定義時にエラーになるので変数名かぶりの心配はないのでは?
関数名かぶりは避けられないですが、さすがにそれをやってしまうような規模で書くならファイルを分けそう。

投稿2017/08/04 06:04

Lhankor_Mhy

総合スコア36115

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

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

退会済みユーザー

退会済みユーザー

2017/08/04 06:17

別のJSファイルに分割すると自動的に即時関数で囲まれて、カプセル化されるのですか? それともconcatしなければ即時関数でカプセル化したことと同じ状態になるのでしょうか? letを使えば確かにすぐに気づきますが、かといってやはり別名にしないといけないことは変わりませんよね。 それなら式の塊ですべて即時関数で囲んでしまった方がいいのかと思ったのですが、 プロの間でもそうでもないのですか?
Lhankor_Mhy

2017/08/04 06:31

あ、プロの方限定の質問だったんですね。 じゃあ私はお呼びじゃないな。 `let`でブロックスコープを使ってもなお名前がかぶるような数の変数をグローバルに置くというのは、さすがに設計が間違ってる気がします。そういう意味では「スコープを変える」派でしょうか。
so87

2017/08/08 02:52

node.jsならばファイルを分ければ別空間になりますよ。 外部に公開したいモノをexportにつっこみます。 Javascriptといってもブラウザとサーバーサイド側でちょこっと違います。 ただ、moduleシステムで統一しようという流れはあります。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/import import/export構文はまだまだ未対応な感じではありますが、 多くの方はBabelというツールを使って、 Javascriptのモジュール問題に対応しています。
退会済みユーザー

退会済みユーザー

2017/08/15 02:23

別のjsファイルにするとNodejsは、すべて即時関数で囲まれたのと同じように、別スコープになるのですね。 フロントjsはならないのでしょうか?
so87

2017/08/16 02:17

node.jsでは別スコープとなります。 下記のようなtype="module"が理解できるブラウザではスコープも別になります。 <script type="module"></script> 2017年8月現在、一部のブラウザでしか対応できていないのでご注意下さい。 理解できないブラウザはscriptブロックを無視します。
guest

0

必要があれば囲むし、必要なければ囲まないでしょう
名前空間の話かなとは思うのですが質問に具体性がないので
回答も概要的なものにしかなりえませんね
javascriptは結局prototypeがベースなのでclassのような管理は難しい旨
以前どなたかが解説されていたかと記憶にあります

投稿2017/08/04 05:30

yambejp

総合スコア114843

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

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

退会済みユーザー

退会済みユーザー

2017/08/04 05:34

例えば 計算1 計算2 計算3 と会った場合三つをそれぞれ即時関数で囲んでカプセル化するかどうかです。 そうしないと名前が被る問題がありますよね。 後半の件は、私は知りません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問