console.log(a) //output:ƒ a(){}
var a = 1;
function a(){};
var a = 10;
console.log(a) //output:10
====================
var a = 1;
if(true){
function a(){};
var a = 10;
}
console.log(a) // this code throws Uncaught SyntaxError: Identifier 'a' has already been declared
上記の両方のコードスニペットは、if block.whyがエラーをスローすることを除いて同じですが、JavaScriptで以下のようにvarを使用して同じスコープ内で同じ変数を2回Delcareできる場合にエラーがスローされます
function a(){};
var a = 10; //no error
また、上記のコードで `var a = 10からvarを削除した後の少し異なるシナリオでは、正常に機能しますが、出力は意外です
var a = 1;
if(true) {
function a(){};
a = 10;
}
console.log(a) //output:ƒ a(){}
If内で宣言された2つの変数が、javascript varはブロックのスコープではなく機能のスコープを尊重するので、上記で宣言された同じ変数を参照するため、この出力を見て驚いています。 10歳?ここで、以下のコードは、関数定義を関数式に置き換えたときに期待どおりに10を出力します。
var a = 1;
if(true) {
var a = function(){ console.log() }
a = 10;
}
console.log(a) //output:10
Javascript
var
はブロックスコープを考慮せず、機能スコープを考慮しているため、これは驚くべきことです...
もちろん、ブロックスコープのvar
の宣言にa
を使用していません。 doesがブロックスコープを尊重する関数宣言を使用しました (それ以外の場合は ES5 strictモードのように、完全に無効なコード )。
以下のように
var
を使用して、同じスコープ内で同じ変数を2回宣言することは、JavaScriptでは許可されています。
ここでも同じことが言えます。ブロック内のfunction
宣言はES6宣言セマンティクス(let
またはconst
など)を使用しているため、再宣言はできません。
ケース1
console.log(a) //output:ƒ a(){}
var a = 1;
function a(){};
var a = 10;
console.log(a) //output:10
としてレンダリングされます
var a;
a = function(){}; // now a holds the value as a function
console.log(a); // output : f a(){}
a = 1; // a is a var that holds value 1
a = 10; // a is a var that holds value 10
console.log(a); // output : 10
ケース2
var a = 1;
if(true){
function a(){};
var a = 10;
}
console.log(a)
としてレンダリングされます
var a;
a = 1;
if(true) {
a = function() {};
let a; // The function declaration in the block uses ES6 declaration semantics (like let or const), which does not allow re-declarations.
var a; // throws Uncaught SyntaxError: Identifier 'a' has already been declared
a = 10;
}
console.log(a);
ケース
var a = 1;
if(true){
function a(){};
a = 10;
}
console.log(a)
としてレンダリングされます
var a;
a = 1;
if(true) {
a = function() {};
let a;
a = 10;
}
console.log(a); // output : f a(){}
ケース4
var a = 1;
if(true){
var a= function(){console.log()}
a = 10;
}
console.log(a)
としてレンダリングされます
var a;
a = 1;
if(true) {
a = function(){console.log()}
a = 10;
}
console.log(a) // output:10
ケース5
var a = 1;
if(true){
function a(){};
a = 10;
console.log(a)
}
console.log(a)
としてレンダリングされます
var a;
a = 1;
if(true){
a = function() {};
let a;
a = 10;
console.log(a); // output:10
}
console.log(a); // output : f a(){}
これに対する簡単な解決策は、IIFEを使用することです。
(function() {
var sahil = {
checkThis: function() {
console.log(this);
function checkOther() {
console.log(this);
}
checkOther(); // checkThis() function called in "global context", will
// return "this" as "window"
}
};
var moo = sahil.checkThis;
moo(); // moo() function called in "global context", will return "this" as "window" })();