web-dev-qa-db-ja.com

高度なJavaScript:この関数が括弧で囲まれているのはなぜですか?

可能性のある複製:
JavaScriptの(function(){})()コンストラクトとは?

私はこのちょっとしたJavaScriptコードに出会いましたが、それをどうすればよいのか分かりません。このコードを実行すると「1」が表示されるのはなぜですか? (1)のこの奇妙な小さな付録とは何ですか?また、関数が括弧で囲まれているのはなぜですか?

(function(x){
    delete x;
    return x;
})(1);
114
nerdess

ここでいくつかのことが行われています。最初は すぐに呼び出される関数式 (IIFE)パターンです:

(function() {
  // Some code
})();

これにより、独自のスコープでJavaScriptコードを実行する方法が提供されます。通常、関数内で作成された変数がグローバルスコープに影響しないように使用されます。代わりにこれを使用できます:

function foo() {
  // Some code
}
foo();

ただし、これには関数に名前を付ける必要がありますが、これは必ずしも必要ではありません。名前付き関数を使用すると、将来のある時点で関数が再度呼び出される可能性があり、望ましくない可能性があります。この方法で匿名関数を使用すると、一度だけ実行されるようになります。

次の構文は無効です。

function() {
  // Some code
}();

関数を式として解析するには、関数を括弧で囲む必要があるためです。詳細はこちら: http://benalman.com/news/2010/11/immediately-invoked-function-expression/

したがって、IIFEパターンをすばやく要約するには:

(function() {
  // Some code
})();

インラインで記述されたかのように、すぐに実行される「一部のコード」を許可しますが、グローバル名前空間に影響を与えないように独自のスコープ内で実行されます(したがって、潜在的に他のスクリプトに干渉または干渉されます)。

通常の関数と同じように、関数に引数を渡すことができます。たとえば、

(function(x) {
  // Some code
})(1);

したがって、関数に最初の引数として値「1」を渡し、関数は、xという名前のローカルスコープ変数として値を受け取ります。

第二に、あなたは機能コード自体の本質を持っています:

delete x;
return x;

削除演算子は、オブジェクトからプロパティを削除します。変数は削除しません。そう;

var foo = {'bar':4, 'baz':5};
delete foo.bar;
console.log(foo);

これがログに記録される結果:

{'baz':5}

一方、

var foo = 4;
delete foo;
console.log(foo);

fooはプロパティではなく変数であり、削除できないため、値4を記録します。

多くの人は、autoglobalsが機能する方法のために、deleteが変数を削除できると想定しています。最初に宣言せずに変数に代入すると、実際には変数ではなく、グローバルオブジェクトのプロパティになります。

bar = 4; // Note the lack of 'var'. Bad practice! Don't ever do this!
delete bar;
console.log(bar); // Error - bar is not defined.

今回は、変数を削除するのではなく、グローバルオブジェクトのプロパティを削除するため、削除が機能します。実際には、前のスニペットはこれと同等です:

window.bar = 4;
delete window.bar;
console.log(window.bar);

これで、foo変数の例ではなく、fooオブジェクトの例に似ていることがわかります。

234
Howard

これは、匿名関数を作成し、パラメーター1で呼び出すことを意味します。

次と同じです:

function foo(x) {
    delete x;
    return x;
}
foo(1);
11
xdazz

通常、人々はこれらを「即時に呼び出される関数式」または「自己実行関数」と呼びます。

これを行うポイントは、その関数内で宣言された変数が外部にリークしないことです。

2
hugomg

それでも1が返される理由は、deleteキーワードがオブジェクトのプロパティを削除するためであることです。残りは他の人がコメントしたように、括弧で囲まれたものはすべて関数として実行され、括弧の2番目のセットはそのブロックに渡される引数です。

deleteのMDNリファレンス 、および closureのMDNリファレンス は、匿名関数についても説明しています。

2
dmp