99

Ben Cherry による JavaScript のスコーピングとホイストに関する素晴らしい記事を読みました。

var a = 1;

function b() {
    a = 10;
    return;

    function a() {}
}
b();
alert(a);

上記のコードを使用すると、ブラウザは「1」を警告します。

「1」を返す理由はまだわかりません。彼の言うことのいくつかが頭に浮かびます: すべての関数宣言は一番上に持ち上げられます。関数を使用して変数のスコープを設定できます。まだクリックしません。

4

18 に答える 18

131

関数ホイストとは、関数がそのスコープの一番上に移動されることを意味します。あれは、

function b() {  
   a = 10;  
   return;  
   function a() {} 
} 

インタピーターによってこれに書き換えられます

function b() {
  function a() {}
  a = 10;
  return;
}

変ですよね?

また、この場合、

function a() {}

と同じように振る舞った

var a = function () {};

したがって、本質的に、これがコードが行っていることです。

var a = 1;                 //defines "a" in global scope
function b() {  
   var a = function () {}; //defines "a" in local scope 
   a = 10;                 //overwrites local variable "a"
   return;      
}       
b();       
alert(a);                 //alerts global variable "a"
于 2011-09-21T21:33:14.163 に答える
6

覚えておく必要があるのは、関数全体を解析し、すべての変数宣言を解決してから実行することです。そう....

function a() {} 

本当になる

var a = function () {}

var aそれをローカルスコープに強制し、変数スコープは関数全体を通過するため、関数にすることで a をローカルスコープに宣言したため、グローバル a 変数は 1 のままです。

于 2011-09-21T21:27:31.883 に答える
5

関数aは関数内に持ち上げられますb

var a = 1; 
function b() { 
   function a() {} 
   a = 10; 
   return;
} 
b(); 
alert(a);

これはほとんど使用するようなものですvar

var a = 1; 
function b() { 
   var a = function () {};
   a = 10; 
   return;
} 
b(); 
alert(a);

関数はローカルで宣言され、設定aはローカルスコープでのみ行われ、グローバル変数では行われません。

于 2011-09-21T21:30:52.277 に答える
1

function a() { }関数ステートメントであり、関数にaローカルな変数を作成しbます。or関数ステートメントが実行される
かどうかに関係なく、関数が解析されるときに変数が作成されます。var

a = 10このローカル変数を設定します。

于 2011-09-21T21:29:46.197 に答える
1

巻き上げは、わかりやすくするために私たちが作った概念です。実際に何が起こるかというと、スコープに関して最初に宣言が行われ、その後に割り当てが行われます (同時にではありません)。

宣言が行われるとvar afunction bそのbスコープ内でfunction aが宣言されます。

この関数 a は、グローバル スコープからの変数 a をシャドウします。

宣言が完了すると、値の割り当てが開始され、グローバルaが値を取得1し、内部function bが取得されます10。するとalert(a)、実際のグローバルスコープ変数が呼び出されます。コードへのこの小さな変更により、より明確になります

        var a = 1;

    function b() {
        a = 10;
        return a;

        function a() { }
    }

    alert(b());
    alert(a);
于 2015-04-14T14:40:13.637 に答える
0

スコープ & クロージャー & 巻き上げ (var/function)

  1. scpope : グローバル var は任意の場所 (ファイル スコープ全体) でアクセスでき、ローカル var はローカル スコープ (関数/ブロック スコープ) からのみアクセスできます。
    注: 関数内で var キーワードを使用しないローカル変数は、グローバル変数になります。
  2. クロージャー : ローカル スコープ (親関数) とグローバル スコープにアクセスできる、他の関数内の関数ですが、他のユーザーは変数にアクセスできません。それ以外の場合は、戻り値として返してください!
  3. 巻き上げ: 値または null を割り当てるよりも、すべての宣言/宣言解除の変数/関数をスコープの上部に移動します!
    注: 値を移動するのではなく、宣言を移動するだけです!

var a = 1;                
//"a" is global scope
function b() {  
   var a = function () {}; 
   //"a" is local scope 
   var x = 12; 
   //"x" is local scope 
   a = 10;
   //global variable "a" was overwrited by the local variable "a"  
   console.log("local a =" + a);
   return console.log("local x = " + x);
}       
b();
// local a =10
// local x = 12
console.log("global a = " + a);
// global a = 1
console.log("can't access local x = \n");
// can't access local x = 
console.log(x);
// ReferenceError: x is not defined

于 2016-12-17T14:25:22.120 に答える
0

変数名が関数名と同じで「a」を意味するために発生しています。したがって、Javascript ホイストにより、名前の競合を解決しようとし、a = 1 を返します。

「JavaScriptホイスト」に関するこの投稿を読むまで、私もこれについて混乱していましたhttp://www.ufthelp.com/2014/11/JavaScript-Hoisting.html

それが役に立てば幸い。

于 2014-11-16T12:55:54.893 に答える
0

これは、より多くの注釈と、遊んでみるための付随するフィドルを含む回答の要約です。

// hoisting_example.js

// top of scope ie. global var a = 1
var a = 1;

// new scope due to js' functional (not block) level scope
function b() {
    a = 10; // if the function 'a' didn't exist in this scope, global a = 10
  return; // the return illustrates that function 'a' is hoisted to top
  function a(){}; // 'a' will be hoisted to top as var a = function(){};
}

// exec 'b' and you would expect to see a = 10 in subsequent alert
// but the interpreter acutally 'hoisted' the function 'a' within 'b' 
// and in doing so, created a new named variable 'a' 
// which is a function within b's scope
b();

// a will alert 1, see comment above
alert(a);

https://jsfiddle.net/adjavaherian/ffpxjx7/

于 2016-05-09T18:41:35.223 に答える
0

巻き上げは JavaScript の動作概念です。巻き上げ(移動など)は、変数を宣言する方法と場所を説明する概念です。

JavaScript では、関数の宣言と変数の宣言は常に、JavaScript インタープリターによってそれらを含むスコープの先頭に見えないように移動 (「ホイスト」) されるため、使用後に変数を宣言できます。

ほとんどの場合、2 種類の巻き上げに遭遇します。

1.変数宣言の巻き上げ

このコードでこれを理解しましょう。

 a = 5; // Assign 5 to a
 elem = document.getElementById("demo"); // Find an element 
 elem.innerHTML = a;                     // Display a in the element
 var a; // Declare a
  //output-> 5

ここで、変数 a の宣言は、コンパイル時に JavaScript インタープリターによって目に見えないようにトップにホストされます。これで a の値を取得できました。しかし、変数を宣言するこのアプローチはお勧めできません。なぜなら、このようにすでにトップに変数を宣言しなければならないからです。

 var a = 5; // Assign and declare 5 to a
 elem = document.getElementById("demo"); // Find an element 
 elem.innerHTML = a;                     // Display a in the element
  // output -> 5

別の例を考えてみましょう。

  function foo() {
     console.log(x)
     var x = 1;
 }

実際には次のように解釈されます。

  function foo() {
     var x;
     console.log(x)
     x = 1;
  }

この場合、x は未定義になります

変数の宣言を含むコードが実行されたかどうかは問題ではありません。この例を考えてみましょう。

  function foo() {
     if (false) {
         var a = 1;
     }
     return;
     var b = 1;
  }

この関数は次のようになります。

  function foo() {
      var a, b;
      if (false) {
        a = 1;
     }
     return;
     b = 1;
  }

変数宣言では、割り当てではなく、変数定義のみが巻き上げられます。

  1. 関数宣言の巻き上げ

変数の巻き上げとは異なり、関数本体または割り当てられた値も巻き上げられます。このコードを検討してください

 function demo() {
     foo(); // this will give error because it is variable hoisting
     bar(); // "this will run!" as it is function hoisting
     var foo = function () {
         alert("this would not run!!");
     }
     function bar() { 
         alert("this will run!!");
     }
 }
 demo();

変数と関数の巻き上げの両方を理解したので、このコードを理解しましょう。

var a = 1;
function b() {
  a = 10;
  return;
   function a() {}
}
b();
alert(a);

このコードは次のようになります。

var a = 1;                 //defines "a" in global scope
 function b() {  
   var a = function () {}; //defines "a" in local scope 
    a = 10;                 //overwrites local variable "a"
    return;      
 }       
 b();       
 alert(a); 

関数 a() は、b() 内にローカル スコープを持ちます。a() は、その定義でコードを解釈している間 (関数ホイストの場合のみ) 先頭に移動されるため、 a はローカル スコープを持つようになり、したがって a のグローバル スコープには影響しませんが、関数 b() 内に独自のスコープがあります。 .

于 2018-05-01T07:20:31.087 に答える