JavaScriptで、かっこを使用して関数を呼び出すと違いがありますか?


105

括弧が空の関数を呼び出すとき、または括弧をまったく付けずに関数を呼び出すときの違いに気づきました。しかし、私は関数に引数を渡していないので、何が違うのでしょうか?

window.onload = initAll();

そして

window.onload = initAll;

その背後にある原理を説明してください。


24
@JS Bangs-米国英語のみ。他ではありません。プログラマーは混乱を避けるためにそれらを「括弧」と呼ぶ傾向がありますが、英国英語では、丸められた括弧は単に括弧として知られています。正方形のものは「角かっこ」と呼ばれます。en.wikipedia.org/wiki/Bracket
Rob Levine

13
重大な注意として、公式のUNICODE名は括弧です。0028 ( LEFT PARENTHESIS =左括弧(1.0)と0029 ) 右括弧=閉じ括弧(1.0) - unicode.org/charts/charindex.html#P と何Dictionary.comはそれについて言っている- dictionary.reference.com/参照/括弧 "直立した曲線のいずれかまたは両方(()..."

8
したがって、これは単なる「米国英語」のものではなく、UNICODEが国際標準であるため、国際標準の定義です。

2
@fuzzy-あなたはどこから真面目に事実を入手しますか?{}かぎカッコと呼ばれます。
Anurag

7
@fuzzy lollipop-Unicodeは、名前ではなくバイトとして文字をエンコードする国際標準です。Unicodeドキュメントの作成者は、文字の名前が国際標準であると主張していません。それは彼らが定義している文字対コードです。ただし、[と]を角かっこ( "ブラケット"だけでなく)としても参照し、[、{および(を角かっことして使用するすべての文字として使用します。ニュアンスを理解するように努めてください。異なる場所で同じ単語を使用する方法で。国際チームの一員である場合は非常に重要です
Rob Levine

回答:


161
window.onload = initAll();

これ initAll() すぐに実行され関数の戻り値をに割り当てますwindow.onload。これは通常はありませんあなたが欲しいもの。initAll()これが意味をなすためには、関数を返す必要があります。

window.onload = initAll;

これにより、実際の関数が割り当てwindow.onloadられます。これは、JavaScriptでは@Felixが言うように、関数を実行することなく、ファーストクラスオブジェクトだからです。initAllloadイベントによって実行されます。


18
ここで重要なのは、関数はJavaScriptのファーストクラスオブジェクトであることです。
フェリックスクリング

136

ペッカの言うことは正しいですが、関数ポインタやデリゲートを完全に理解していない人に説明するのに役立つ例を少し詳しく説明したいと思います。

これはwindow.onloadデモンストレーションが少し工夫されているので、使用しません。代わりに、単純な乗算関数を使用してデモを行います。

function Multiply(operator, operand) {
    return operator * operand;
}

これは同様に書くことができます:

Multiply = function(operator, operand) {
    return operator * operand;
}

最初の例ではその意味が明らかではないかもしれませんが、2番目の例は、2つのパラメーターを持つ関数をと呼ばれる変数に割り当てていることをより明確に示しています。割り当てMultiplyとしての関数のこの概念は、JavaScript全体で共通です。これは、関数が「ファーストクラスの市民」であるという事実の小さなデモです。つまり、関数は、値を渡すように正確に渡すことができます。

それでは、割り当ての違いを見てみましょう。

var operator = 3;
var operand = 4;
var ret = Multiply(operator, operand);

ret変数を定義する時点で、Multiplyが実行され、戻り値が割り当てられますret-12になります。

別の方法でもう一度試してみましょう。

var operator = 3;
var operand = 4;
var ret = Multiply;

これで、を定義した時点で、関数から取得した結果ではなく、関数retretなります。to を呼び出すと、関数が実行され、呼び出した場合とまったく同じように呼び出すことができます。MultiplyMultiplyret()MultiplyMultiply(operator, operand)

var out = ret(3, 4);

と同じです

var out = Multiply(3, 4);

あなたはret、のデリゲートとして使用するつもりであると効果的に述べましたMultiply()。を呼び出すときはret、実際にはMultiply関数を指します。

に戻るwindow.onload。これを次のように考えてください:

window.onload = function() {
    //Doing what all good window.onload functions should do...
}

initAll = function() {
    return 12;
}

ご覧のとおり、window.onload他の関数と同じような関数であり、特別なことは何もありません。値を割り当てたり、関数を割り当てたり、必要に応じてnullにしたりできます。重要なのwindow.onloadは、独自の関数よりも特別なことは何もないということです。わずかに異なるのは、ロード時にウィンドウによって呼び出されることです。[免責事項:ウィンドウ関数を実際に無効にしたことはないので、これが悪影響をもたらすかどうかはわかりません。関数を呼び出す前に関数が割り当てられているかどうかを確認することを期待しif (window.onload) window.onload();ます。つまり、]です。

ここでinitAll()私たちが言っていることは、次のとおりです。

window.onload = initAll();

これは言うかもしれません:

window.onload = 12;

しかしinitAll、括弧なしで言うとき、私たちが本当に言っているのは、window.onload関数を新しい関数で置き換えたいです。つまりinitAll、これを関数で置き換えてwindow.onloadinitAllコード。

そう:

window.onload = function() {
    //Doing what all good window.onload functions should do...
}

に置き換えられます:

window.onload = function() {
    return 12;
}

したがって、を呼び出すと、元々あった関数の代わりに関数window.onloadが実行されます。元の関数を新しい関数に置き換えました。initAllwindow.onload

実際、次のように書くこともできます。

window.onload = function() {
    //Write all your init code right in here instead of having a separate 
    //initAll function.
}

より良い例としては、次のようなものがあります。

var d = new Date();
var currentTime = d.getTime();

その時点dで定義されていたものは何でも、最終的にはに割り当てられcurrentTimeます。すばらしいですが、そのコードを含む関数がいつ呼び出されたか(つまり、ページの読み込み時)を調べたい場合にのみ役立ちます。currentTime呼び出されたときにいつでも現在の時刻が必要な場合はどうなりますか?

var currentTime = function() {
    var d = new Date();
    return d.getTime();
}

var a = currentTime(); //The current time at the point a is defined...
var b = currentTime;   //b is a functional reference to currentTime...
var c = b(); //The current time when variable c is defined
var d = c; //The current time when variable c was defined

呼び出し可能な方法b()で、cd割り当てを呼び出す方法に注意してくださいcurrentTime()


素晴らしい答え!
Shadi Almosri 2016

ちょっと、イベントリスナーで引数を取る関数を追加したい場合はどうなりますか?
シェミロト2018

16

JavaScriptの関数は一流の市民であるため、他の変数に割り当てたり、引数として渡すことができます。

だから、あなたがするとき

window.onload = initAll;

関数自体を参照するようにオブジェクトのonloadプロパティを設定しています。windowinitAll

あなたがするとき

window.onload = initAll();

このonloadプロパティはその行で実行されるため、initAll の戻り値を保持するように設定しています。


10

initAll 関数値への参照であり、関数名に追加された大括弧演算子はこの関数オブジェクトを実行します。

だからあなたが何かをした場合

a = initAll

その後a、同じようになりinitAllます-たとえば、あなたがすることができますa()-と

a = initAll()

変数aは、実行されたinitAll関数の戻り値を取得します


8

私は6年遅れていますが、これは上記の回答よりもはるかに簡単に説明できたと思います。

これがTLDRです。または鳥瞰図を使用して関数を呼び出すと、使用しないとき()のを

この関数を例にとってみましょう:

function foo(){
return 123;
}

「foo」をログに記録した場合- なし ()

console.log(foo); 

---outout------
function foo(){
return 123;
}

関数自体()フェッチする手段を使用しない。コールバックとして渡されるようにする場合は、これを行います。


-あなたは「FOOを()」ログインした場合 ()

console.log(foo());
-----output-----
 123

()関数の後に使用することは、関数を実行してその返すことを意味します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.