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

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

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

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

Q&A

解決済

3回答

299閲覧

JavaScriptの即時関数に似たremodal.jsでのコード頭からのNOT演算子の記述が理解できません。

ZET

総合スコア17

JavaScript

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

0グッド

0クリップ

投稿2019/11/19 11:23

!(function(){//..処理..//}());の振る舞いが解りません。

今更ですが、JavaScript(ECMAScript5)を学習中です。

JavaScript

1!function(){ 2 // コード省略 3}());

上記コードは、単純に真偽値を問う即時関数だと解りました。

該当のソースコード

JavaScript

1!(function(root, factory) { 2 // コード省略 3})(this, function(global, $) { 4 // コード省略 5});

しかし、例えば、remodal.jsで現れるJavaScript本体ファイルでの次のコード

発生している問題

即時関数は理解できたのですが、
この場合の即時関数に似た形式を取っている前の
「NOT演算子」が表す関数の振る舞いが全く理解できません。
JQueryが複雑に絡んでいるというより、
JQueryありきのライブラリということは解りました。

試したこと

Googleで検索を2週間ほどかけても納得しうる記事はヒットしません。
唯一がこちらで見かけましたが、御質問者様が理解されているのを前提ですので、
私の抱いている疑問は解けませんでした。

例えば、次のような即時関数があった場合ですが、

JavaScript

1!(function(){ 2 return true; 3}());

これと次の違いはなく、

JavaScript

1!function(){ 2 return true; 3}();

これでは全く同じ結果のfalseが得られることは試して解りました。
また、見かけだけ同じかもしれないと重い、
再確認の意味で、次のように等値演算子で比較したところ、

JavaScript

1 var a =!(function(){return false;}()); 2 var b = !function(){return false;}(); 3  document.write(a===b);

aとbの変数オブジェクトは等しくtrueと出ました。

これは単純に()で囲っているか囲っていないかなので、等しくなるのは
当然と言われれば当然ですが・・・。

推測ですが、ただ、remodal.jsはライブラリとしてJavaScriptファイルのコード全体を
「NOT演算子」でパッケージする必要があるので、

JavaScript

1!(function(root, factory) { 2 // コード省略 3})(this, function(global, $) { 4 // コード省略 5});

このような形式を取っているだけなのか、もっと深い意味があるのか御質問させて頂きます。
曖昧な質問内容で申し訳ありません。
初めての質問ですので、情報の過不足や御無礼がありましたら、何卒御容赦下さいますようお願い申し上げます。
御回答の程、何卒、よろしくお願い申し上げます。

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

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

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

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

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

guest

回答3

0

ベストアンサー

文法

ECMAScript 2019の文法上、"function" を記述して関数定義する文法は二種類あります。

JavaScript

1/** 2 * 関数宣言 3 */ 4function foo () {} 5 6/** 7 * 関数式 8 */ 9const bar = function bar () {};

即時関数

「即時関数」を定義する場合、

  • 変数未定義で即実行
  • 単体の文として成立する

という状況が多いと思いますが、その場合、式文(Expression Statement)として成り立たなければなりません。

式文は「"function" で始まってはならない文法」なので、下記コードは SyntaxError を返します。

JavaScript

1function () {}(); // SyntaxError: Function statements require a function name 2function bar () {}(); // SyntaxError: Unexpected token ')'

"function" で始まらなければ、式文(Expression Statement)の必要条件を満たし、即時関数を書けます。

JavaScript

1(function () { return 1; })(); // 1 2(function () { return 2; }()); // 2 3+function () { return 3; }(); // 3 4-function () { return 4; }(); // -4 5!function () { return 5; }(); // false 6 7/** 8 * 返り値を使わない場合、"()" を使うコード以外は「余計な処理」が働きます 9 */

このように、即時関数は特定の構文を指す呼称ではありません。
「関数定義後に即実行する」という用途で、即時関数と呼ばれます。
書き方は多種多様なので、一つの書き方にとらわれず、他のパターンも考えてみると視野が広がるでしょう。

別例としては、再帰呼び出しする書き方があります。

JavaScript

1(function increment (i) { 2 console.log(i); 3 if (i < 5) increment(++i); 4})(1); // 1 -> 2 -> 3 -> 4 -> 5

アロー関数でも「即時関数」を書けます。

JavaScript

1(() => 6)(); // 6

remodal.js

JavaScript

1!(function($, location, document) { 2 // 中略 3}(window.jQuery || window.Zepto, location, document));

少なくとも、コード単体で見た場合、!無意味な演算子です。
返り値を使うでもなく、() で既に式文になっているわけですから。

先頭にセミコロン挿入のように、前述のコードに働く何がしかの対策かもしれませんが、思いつきません。

特定のライブラリのコードであれば、制作者に尋ねるのが最良と私は思います。

Re: ZET さん

投稿2019/11/19 12:22

編集2019/11/20 09:17
think49

総合スコア18164

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

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

kei344

2019/11/19 12:45

To: think49さん 質問タイトルが「コード頭からのNOT演算子の記述が理解できません」なので、「!(function () {})() について」聞かれているのではないでしょうか。
ZET

2019/11/19 12:52

即時関数のパターンは把握していましたので、その旨を記載すべきでした。 お手数をお掛けして誠に申し訳ありません。 再帰呼び出しの例とアロー関数での例が大変勉強になりました。 どうもありがとうございます。 特に意味がないということが判っただけでも大きな収穫でした。 無意味に深く考えすぎでした。
think49

2019/11/19 13:06 編集

親記事に追記し、remodal.js のコードに言及しました、
ZET

2019/11/19 22:44

昨晩は寝ながら、ライブラリ全体を包むようにNOT演算子があるので、 スコープの関係上、第三者が見たときに視認性を高めるために、あえて ()で囲ったのかなとか思いました。実際に()を外して試してみようと思います。 ご指摘の通り、無意味な演算子かどうかも判ると思います。 しかしながら、脱JQueryの流れが進んでいる今、 そのJQueryの拡張ライブラリとしての位置づけのものですので、 GitHubでご覧頂いた通り、2017年で更新が止まっています。 本当にどうもありがとうございました。
ZET

2019/11/19 22:56

では、使わなければいいという話になりますが、 今後、JQuery関連以外で、 同じコードに直面した時、同様の疑問を抱くのは必然だと思い、 御質問させて頂きました。 どうもありがとうございます。
guest

0

remodal.jsでの意味は知りませんが、コードゴルフ(同じ処理をする一番短い文字数のコードを書く競技)でも使われますね。括弧を使うより1文字短いので。
演算子の右は式が期待されるので、無名関数を呼び出してくれます。

投稿2019/11/19 12:15

otn

総合スコア84555

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

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

kei344

2019/11/19 12:39

括弧があるので短くする意図ではないのでは。
otn

2019/11/19 12:48

括弧があってもなくても同じなのはなぜという質問かと思っての回答ですが、質問を読み返すと、remodal.jsではどうしてこういう記述方法を取るのかという質問だったのですかね。
ZET

2019/11/19 12:53

>otn様 その通りです!!!
guest

0

「NOT演算子」でパッケージする必要があるので、

remodal.jsがどんなものかは知りませんがそういう理由は特になく即時実行出来れば何でもいいと思われます
作った人の好みの書き方というだけでしょう
どこかのサイトで実行速度のテスト結果を載せていたものもあった気がしますが

投稿2019/11/19 11:33

hentaiman

総合スコア6421

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

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

ZET

2019/11/19 22:37

そうだったのですね。 お答え頂きありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問