web-dev-qa-db-ja.com

JavaScriptの変数名と関数名が同じ場合はどうなりますか?

次のコードでは、関数を宣言し、その後に関数と同じ名前の変数を宣言しています。

function a(x) {
    return x * 2;
}

var a;
alert(a);

これはundefinedに警告することを期待していましたが、実行すると、警告に次のように表示されます。

関数a(x) {
return x * 2
}

変数に値を割り当てた場合(var a = 4など)、アラートにはその値(4)が表示されますが、この変更がない場合、aは関数として認識されます。

なんでこんなことが起こっているの?

22
joesid

関数オブジェクトのタイプですのタイプです。

値は変数(およびプロパティ、および関数への引数など)に保存できます。

関数宣言:

  • 名前付き関数を作成します
  • 現在のスコープ内に関数と同じ名前の変数を作成します(そのような変数が既に存在しない場合)
  • 関数をその変数に割り当てます
  • 巻き上げられている

A varステートメント:

  • 指定された名前で現在のスコープに変数を作成します(そのような変数が既に存在しない場合)
  • 巻き上げられている
  • その変数に値を割り当てません(割り当て演算子と組み合わせない限り)

宣言とvarステートメントの両方が巻き上げられます。そのうちの1つだけが変数aに値を割り当てます。

15
Quentin

JavaScriptでは、関数宣言変数宣言の両方が、関数で定義されている場合は関数の最上部に、関数の外ではグローバルコンテキストの最上部に引き上げられます。また、関数宣言は変数宣言よりも優先されます(変数割り当てよりも優先されません)。

巻き上げ時に関数宣言が変数宣言をオーバーライドする

まず、変数を宣言します。

_var a; // value of a is undefined 
_

次に、aの値は関数です。関数の宣言は変数の宣言よりも優先されます(変数の代入よりは優先されません)。

_function a(x) {
  return x * 2;
}
_

そして、それがalert(a);を呼び出すときに得られるものです。

ただし、変数を宣言する代わりに変数の割り当てを行う場合、_var a = 4;_が割り当てられた値_4_が優先されます。

8
Yosvel Quintero

変数名として関数名を使用すると、その値は関数本体に置き換えられます。したがって、「var a」は関数「a」の本体になり、アラートには関数「a」が表示されます。

2
Rahul Agrawal

また、var aは巻き上げられており、このようになっています

var a; // placed

function a(x) {
  return x * 2;
};

var a; // removed
alert (a); // a is replaced by function body

var aは巻き上げられるので、4 to a

var a; // placed

function a(x) {
  return x * 2;
};

var a = 4; // removed
a = 4 // added

alert (a); // a is now 4
2
akinjide

ES6には、letの代わりにconst/varを使用するときにSyntaxError: Identifier (?) has already been declaredを定義することにより、より優れたソリューションが付属しています。

let

function foo () {}
let foo;
// => SyntaxError: Identifier 'foo' has already been declared

const

function foo () {}
const foo = 1;
// => SyntaxError: Identifier 'foo' has already been declared

ご了承ください const foo; 動作しません。 SyntaxError: Missing initializer in const declaration

0
themefield