関数 - javascript 変数 保持




JavaScriptの変数の範囲は何ですか? (18)

オールドスクールのJavaScript

従来、JavaScriptには2つのタイプのスコープしかありませんでした。

  1. グローバルスコープ :変数は、アプリケーションの始めからアプリケーション全体(*)まで知られています。
  2. 機能スコープ :変数は、関数の先頭から、関数の先頭から宣言されている関数内で認識されます(*)。

違いを説明する答えはすでにたくさんあるので、私はこれについて詳述しません。

現代のJavaScript

最新のJavaScript仕様では、第3のスコープも使用できるようになりました。

  1. ブロックスコープ :宣言されたブロック変数は、宣言された瞬間から認識されます(**)

ブロックスコープ変数を作成するにはどうすればよいですか?

伝統的には、次のような変数を作成します。

var myVariable = "Some text";

ブロックスコープ変数は次のように作成されます:

let myVariable = "Some text";

関数スコープとブロックスコープの違いは何ですか?

関数スコープとブロックスコープの違いを理解するには、次のコードを検討してください。

// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here

function loop(arr) {
    // i IS known here, but undefined
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here

    for( var i = 0; i < arr.length; i++ ) {
        // i IS known here, and has a value
        // j IS NOT known here
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    };

    // i IS known here, and has a value
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here

    for( let j = 0; j < arr.length; j++ ) {
        // i IS known here, and has a value
        // j IS known here, and has a value
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    };

    // i IS known here, and has a value
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here
}

loop([1,2,3,4]);

for( var k = 0; k < arr.length; k++ ) {
    // i IS NOT known here
    // j IS NOT known here
    // k IS known here, and has a value
    // l IS NOT known here
};

for( let l = 0; l < arr.length; l++ ) {
    // i IS NOT known here
    // j IS NOT known here
    // k IS known here, and has a value
    // l IS known here, and has a value
};

loop([1,2,3,4]);

// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here

ここで、変数jは最初のforループでのみ認識され、前後では認識されないことがわかります。 しかし、私たちの変数iは関数全体で知られています。

また、ブロックスコープ変数は、ホイストされていないため宣言される前には認識されていないと考えてください。 同じブロックスコープの変数を同じブロック内で再宣言することも許可されていません。 これにより、ブロックスコープ変数は、グローバルにまたは機能的にスコープ化された変数よりもエラーを起こしにくくなります。変数は、ホイストされ、複数の宣言の場合にエラーを生成しません。

今日ブロックスコープ変数を使用するのは安全ですか?

今日の使用が安全かどうかは、使用環境によって異なります。

  • サーバー側のJavaScriptコード( Node.js )を記述している場合は、 letステートメントを安全に使用できます。

  • クライアント側のJavaScriptコードを記述していて、Transizer( Traceur )を使用している場合は、 letステートメントを安全に使用することができますが、コードはパフォーマンスに関して最適なものになる可能性があります。

  • クライアントサイドのJavaScriptコードを記述していて、トランスパイライザを使用していない場合は、ブラウザのサポートを考慮する必要があります。

    現在、2016年2月23日には、 letサポートしていないブラウザや、部分的なサポートしかないブラウザがあります。

    • Internet Explorer 10以降 (サポートなし)
    • Firefox 43以降 (サポートなし)
    • Safari 9以降 (サポートなし)
    • Opera Mini 8以降 (サポートなし)
    • Androidブラウザ4以下(サポートなし)
    • Opera 36以降 (部分的サポート)
    • 丁目51号 (一部支持)

ブラウザのサポートを追跡する方法

この回答を読んでいるときにletステートメントをサポートしているブラウザの最新の概要については、 このCan I Use 」ページを参照してください

(*)グローバル変数と関数スコープ変数は、JavaScript変数がhoistedれて宣言される前に初期化され、使用されます。 これは、宣言が常にスコープの上端にあることを意味します。

(**)ブロックスコープ変数は持ち上げられません

javascriptの変数の範囲は何ですか? 彼らは関数の外ではなく内部で同じスコープを持っていますか? それとも問題なの? また、グローバルに定義されている変数はどこに格納されていますか?


現代Js、ES6 +、 ' const 'と ' let '

他のほとんどの主要言語と同様に、作成する変数ごとにブロックスコープを使用する必要があります。 var時代遅れです。 これにより、コードをより安全に保守しやすくなります。

const95%のケースで使用する必要があります。 可変参照が変更できないようにします。 配列、オブジェクト、およびDOMノードのプロパティは変更でき、おそらくconstはずです。

letは再割り当てが必要な変数に使用する必要があります。 これにはforループが含まれます。 初期化を超えて値を変更した場合は、 let使用letます。

ブロックスコープとは、変数が宣言されている括弧内でのみ使用可能であることを意味します。 これは、スコープ内で作成された匿名関数を含む内部スコープにまで及ぶ。


グローバルスコープ:

グローバル変数はまったく世界の星に似ています(Jackie Chan、Nelson Mandela)。 アプリケーションのどの部分からでもアクセスできます(値を取得または設定します)。 グローバル関数は、グローバルイベント(新年、クリスマス)に似ています。 アプリケーションのどの部分からでも実行(呼び出し)できます。

//global variable
var a = 2;

//global function
function b(){
   console.log(a);  //access global variable
}

ローカルスコープ:

あなたがアメリカにいれば、有名な有名人のキム・カルダシアン(彼女は何とかタブロイドを作っている)を知るかもしれません。 しかし、米国外の人は彼女を認識しません。 彼女は地元の星で、彼女の領土に縛られています。

ローカル変数はローカルスターと似ています。 スコープ内でのみアクセスできます(値を取得または設定します)。 ローカル関数はローカルイベントに似ています - あなたはそのスコープ内でのみ実行できます(祝う)。 範囲外からアクセスする場合は、参照エラーが発生します

function b(){
   var d = 21; //local variable
   console.log(d);

   function dog(){  console.log(a); }
     dog(); //execute local function
}

 console.log(d); //ReferenceError: dddddd is not defined    

範囲の詳細な理解については、この記事をチェックしてください


"Javascript 1.7"(JavascriptへのMozillaの拡張)では、 letステートメントでブロックスコープ変数を宣言することもできます:

 var a = 4;
 let (a = 3) {
   alert(a); // 3
 }
 alert(a);   // 4

ALMOSTには2種類のJavaScriptスコープしかありません:

  • 各var宣言のスコープは、最もすぐに囲む関数に関連付けられています
  • var宣言の囲み関数がない場合は、グローバルスコープです

したがって、関数以外のブロックは新しいスコープを作成しません。 これは、for-loopsがスコープ外の変数を上書きする理由を説明しています。

var i = 10, v = 10;
for (var i = 0; i < 5; i++) { var v = 5; }
console.log(i, v);
// output 5 5

代わりに関数を使う:

var i = 10, v = 10;
$.each([0, 1, 2, 3, 4], function(i) { var v = 5; });
console.log(i,v);
// output 10 10

最初の例では、ブロック範囲がなかったので、最初に宣言された変数は上書きされました。 2番目の例では、関数のために新しい範囲があったため、最初に宣言された変数はSHADOWEDであり、上書きされませんでした。

JavaScriptスコープに関しては、ほとんどのことを知っておく必要があります。

JavaScriptスコープは実際には直感的ではありませんが、実際には非常にシンプルです。 知っておくべきいくつかの事柄:

  • var宣言はスコープの上部に持ち上げられます。 これは、var宣言がどこで発生しても、var自体が先頭にあるかのようにコンパイラに意味します
  • 同じスコープ内の複数のvar宣言が結合されています

したがって、このコード:

var i = 1;
function abc() {
  i = 2;
  var i = 3;
}
console.log(i);     // outputs 1

次のものと同等です。

var i = 1;
function abc() {
  var i;     // var declaration moved to the top of the scope
  i = 2;
  i = 3;     // the assignment stays where it is
}
console.log(i);

これは直感的ではないように思えるかもしれませんが、不可欠な言語設計者の観点からは理にかなっています。


JSには機能スコープしかありません。 スコープをブロックしないでください! 何が巻いているのかを見ることができます。

var global_variable = "global_variable";
var hoisting_variable = "global_hoist";

// Global variables printed
console.log("global_scope: - global_variable: " + global_variable);
console.log("global_scope: - hoisting_variable: " + hoisting_variable);

if (true) {
    // The variable block will be global, on true condition.
    var block = "block";
}
console.log("global_scope: - block: " + block);

function local_function() {
    var local_variable = "local_variable";
    console.log("local_scope: - local_variable: " + local_variable);
    console.log("local_scope: - global_variable: " + global_variable);
    console.log("local_scope: - block: " + block);
    // The hoisting_variable is undefined at the moment.
    console.log("local_scope: - hoisting_variable: " + hoisting_variable);

    var hoisting_variable = "local_hoist";
    // The hoisting_variable is now set as a local one.
    console.log("local_scope: - hoisting_variable: " + hoisting_variable);
}

local_function();

// No variable in a separate function is visible into the global scope.
console.log("global_scope: - local_variable: " + local_variable);

JavaScriptコード(グローバルコードまたは関数)のすべてのチャンクには、スコープチェーンが関連付けられています。 このスコープチェーンは、そのコードの「範囲内」の変数を定義するオブジェクトのリストまたはチェーンです。 JavaScriptが変数x変数解決と呼ばれるプロセス)の値を参照する必要がある場合、まずチェーン内の最初のオブジェクトを調べます。 そのオブジェクトにxという名前のプロパティがある場合、そのプロパティの値が使用されます。 最初のオブジェクトにxという名前のプロパティがない場合、JavaScriptはチェーン内の次のオブジェクトで検索を続けます。 2番目のオブジェクトにxという名前のプロパティがない場合、検索は次のオブジェクトに移動します。 xがスコープチェーン内のオブジェクトのプロパティでない場合、 xはそのコードのスコープ内になく、ReferenceErrorが発生します。 トップレベルのJavaScriptコード(つまり、関数定義内に含まれていないコード)では、スコープチェーンはグローバルオブジェクトである単一のオブジェクトで構成されています。 ネストされていない関数では、スコープチェーンは2つのオブジェクトで構成されています。 1つは関数のパラメータとローカル変数を定義するオブジェクトで、2つ目はグローバルオブジェクトです。 ネストされた関数では、スコープチェーンには3つ以上のオブジェクトがあります。 この一連のオブジェクトがどのように作成されるのかを理解することが重要です。 ファンクションがDEFINEDの場合、有効なスコープ・チェーンが格納されます。 その関数がINVOKEDされると 、ローカル変数を格納する新しいオブジェクトを作成し、その新しいオブジェクトを格納されたスコープチェーンに追加して、その関数呼び出しのスコープを表す新しい長いチェーンを作成します。 これは、外部関数が呼び出されるたびに内部関数が再び定義されるため、ネストされた関数の方が面白くなります。 スコープチェーンは外部関数の呼び出しごとに異なるため、定義されるたびに内部関数は微妙に異なります。 内部関数のコードは外部関数の呼び出しごとに同じですが、スコープチェーンはその関数に関連付けられていますコードは異なります。 スコープチェーンのこの概念は、クロージャを理解するために重要です。


Javascriptでは、スコープチェーンを使用して、指定された関数のスコープを設定します。 通常はグローバルスコープが1つあり、定義された各関数には独自のネストスコープがあります。 別の関数内で定義された関数は、外部関数にリンクされたローカルスコープを持ちます。 スコープを定義するのは常にソース内の位置です。

スコープチェーン内の要素は、基本的に親スコープへのポインタを持つMapです。

変数を解決するとき、javascriptは最も内側のスコープから開始し、外側を検索します。


JavaScriptには2種類のスコープがあります。

  1. グローバルスコープグローバルスコープで発表される変数は、プログラム内のどこでも非常にスムーズに使用できます。例えば:

    var carName = " BMW";
    
    // code here can use carName
    
    function myFunction() {
         // code here can use carName 
    }
    
  2. 機能スコープまたはローカルスコープ:このスコープで宣言された変数は、それ自身の関数でのみ使用できます。例えば:

    // code here can not use carName
    function myFunction() {
       var carName = "BMW";
       // code here can use carName
    }
    

JavaScriptには2種類のスコープがあります:

  • ローカルスコープ
  • グローバルスコープ

Below関数には、ローカルスコープ変数がありますcarName。この変数は関数の外部からはアクセスできません。

function myFunction() {
    var carName = "Volvo";
    alert(carName);
    // code here can use carName
}

下位クラスには、グローバルスコープ変数がありますcarName。この変数は、クラス内のどこからでもアクセスできます。

class {

    var carName = " Volvo";

    // code here can use carName

    function myFunction() {
        alert(carName);
        // code here can use carName 
    }
}

この興味深い例を試してみてください。以下の例では、aが0で初期化された数値だった場合、0と1が表示されます。aはオブジェクトであり、javascriptはf1にaのコピーではなくaのポインタを渡します。その結果、同じ警告が両方の時間に発生します。

var a = new Date();
function f1(b)
{
    b.setDate(b.getDate()+1);
    alert(b.getDate());
}
f1(a);
alert(a.getDate());


グローバル:関数の外で宣言された変数

Local:関数内で宣言された変数で、そのスコープ内でのみ呼び出すことができます


コードを実行します。 これがスコープについての考えを与えることを願って

Name = 'global data';
document.Name = 'current document data';
(function(window,document){
var Name = 'local data';
var myObj = {
    Name: 'object data',
    f: function(){
        alert(this.Name);
    }
};

myObj.newFun = function(){
    alert(this.Name);
}

function testFun(){
    alert("Window Scope : " + window.Name + 
          "\nLocal Scope : " + Name + 
          "\nObject Scope : " + this.Name + 
          "\nCurrent document Scope : " + document.Name
         );
}


testFun.call(myObj);
})(window,document);

私は、JavaScriptを初めて使う多くの人が、言語でデフォルトで継承が利用可能であり、関数スコープがこれまでの唯一のスコープであることを理解するのに問題があることを発見しました。 私は、昨年末に書いた美容院の拡張部を、「ジャグレティー」と呼んだ。 フィーチャカラーはコード内のスコープを機能させ、常にそのスコープで宣言されたすべての変数にカラーを関連付けます。 あるスコープの色を持つ変数が別のスコープで使用されている場合、クロージャは視覚的に示されます。

次の場所で機能を試してください:

デモをご覧ください:

コードを表示する場所:

現在、この機能は深さ16のネストされた関数をサポートしていますが、現在はグローバル変数に色付けされていません。


私はあなたが勉強するための例をたくさん与えることができる最高のことを考えます。 Javascriptのプログラマーは、スコープをどれだけうまく理解しているかによって、実際にランク付けされています。 時には、直感に反することもあります。

  1. グローバルスコープ変数

    // global scope
    var a = 1;
    
    function one() {
      alert(a); // alerts '1'
    }
    
  2. ローカルスコープ

    // global scope
    var a = 1;
    
    function two(a) { // passing (a) makes it local scope
      alert(a); // alerts the given argument, not the global value of '1'
    }
    
    // local scope again
    function three() {
      var a = 3;
      alert(a); // alerts '3'
    }
    
  3. 中級JavaScriptのブロックスコープのようなものはありません (ES5; ES6ではlet導入let

    a。

    var a = 1;
    
    function four() {
      if (true) {
        var a = 4;
      }
    
      alert(a); // alerts '4', not the global value of '1'
    }
    

    b。

    var a = 1;
    
    function one() {
      if (true) {
        let a = 4;
      }
    
      alert(a); // alerts '1' because the 'let' keyword uses block scoping
    }
    
  4. 中級オブジェクトのプロパティ

    var a = 1;
    
    function Five() {
      this.a = 5;
    }
    
    alert(new Five().a); // alerts '5'
    
  5. 上級者閉鎖

    var a = 1;
    
    var six = (function() {
      var a = 6;
    
      return function() {
        // JavaScript "closure" means I have access to 'a' in here,
        // because it is defined in the function in which I was defined.
        alert(a); // alerts '6'
      };
    })();
    
  6. 上級者プロトタイプベースのスコープ解決

    var a = 1;
    
    function seven() {
      this.a = 7;
    }
    
    // [object].prototype.property loses to
    // [object].property in the lookup chain. For example...
    
    // Won't get reached, because 'a' is set in the constructor above.
    seven.prototype.a = -1;
    
    // Will get reached, even though 'b' is NOT set in the constructor.
    seven.prototype.b = 8;
    
    alert(new seven().a); // alerts '7'
    alert(new seven().b); // alerts '8'
    
  7. グローバル+ローカル余分な複雑なケース

    var x = 5;
    
    (function () {
        console.log(x);
        var x = 10;
        console.log(x); 
    })();
    

    JavaScriptは常に変数宣言(初期化ではない)をスコープの先頭に移動するので、コードは次のようになります。

    var x = 5;
    
    (function () {
        var x;
        console.log(x);
        x = 10;
        console.log(x); 
    })();
    
  8. Catch節スコープ変数

    var e = 5;
    console.log(e);
    try {
        throw 6;
    } catch (e) {
        console.log(e);
    }
    console.log(e);
    

    これで5,6,5が印刷されます。 catch節の内部では、グローバル変数とローカル変数をシャドウします。 しかし、この特別なスコープはキャッチされた変数に対してのみです。 あなたがvar f;を書くならばvar f; catch節の中で、try-catchブロックの前後に定義したのとまったく同じです。


EcmaScript5には主に2つのスコープ、つまりローカルスコープグローバルスコープがありますが、EcmaScript6には主に3つのスコープ、ローカルスコープ、グローバルスコープ、ブロックスコープと呼ばれる新しいスコープがあります

ブロックスコープの例は次のとおりです。

for ( let i = 0; i < 10; i++)
{
 statement1...
statement2...// inside this scope we can access the value of i, if we want to access the value of i outside for loop it will give undefined.
}

私の理解は、3つのスコープがあることです。グローバルスコープは、グローバルに利用可能です。ブロックに関係なく機能全体で使用可能なローカルスコープ。ブロックスコープは、使用されたブロック、ステートメント、または式でのみ使用できます。グローバルスコープとローカルスコープは、関数または外部のいずれかでキーワード 'var'で示され、ブロックスコープはキーワード 'let'で示されます。

グローバルスコープとローカルスコープしかないと思う人には、MozillaがJSのブロックスコープのニュアンスを説明するページ全体を持つ理由を説明してください。

let







var