【ES 6基礎】letとスコープ

11692 ワード

ECMAScriptはEcma国際(前身はヨーロッパコンピュータメーカー協会)がJavaScriptをベースに作成したスクリプト言語標準です.現在、この標準は基本的に毎年一回の新しいES規格を発表しています.現在の最新の標準はECMAScript 2018(ES 9)です.先端開発の応用シーンがますます複雑になっているため、時間が六年間かかりました.したがって、私たちはJavaScriptを新たに学ぶ必要があります.これで先端の日進月歩の発展に適応できます.
今日から、小编はES 6及びこれからの関连内容を绍介します.この文章の小编は皆さんと一绪に新しい文法letを使って変数を宣言する方法を勉强します.
この文章は10分間読む予定です.
以下の内容を学びます.
  • let基本紹介
  • 作用域の紹介
  • 作用領域
  • グローバルスコープと関数スコープ
  • ブロック級作用領域
  • varとletの違い
  • 変数を繰り返し定義する問題
  • 概念を高める問題
  • let紹介
    ES 6はletを導入し、変数をletで宣言し、JavaScriptがブロックレベルのスコープがない問題を解決しました.
    他の言語背景があります.例えばJAVA、C〓の開発者にとって、この概念は理解しにくくなくて、ES 6の前に、JavaScriptはブロックレベルの機能領域がありません.新米にとって、var宣言変数を使うと、JavaScriptが分かりにくくて、デバッグしにくくなります.なぜこのようになったのか、主に作用域の概念がよく分かりませんでした.次に私達はまず何が作用域なのかを知ります.
    スコープ
    スコープは簡単に言えば、変数を探すためのルールです.どこで変数を検索するか、どのように変数を検索しますか?これらの変数はどこにありますか?それらはどこに保存されていますか?コンパイラはどうやってそれらを見つけますか?ES 6コードの前に、グローバルスコープまたは関数スコープだけがあります.
    他の関数にブロックまたは関数がネストされると、スコープネストが発生します.図に示すように、3つのネスト作用領域があります.
  • グローバルスコープには、一つの識別子があります.
  • fooによって作成された関数領域には、3つの識別子があります.a、bar、b(黄色領域全体)
  • barによって作成された関数的スコープには、識別子があります.c(青色領域)
  • どうやってネストされたスコープの中で変数を探しますか?エンジンは現在のスコープから変数を探し始めます.見つけられないと、前のレベルに進みます.最外層のグローバルスコープに到達すると、見つけても見つけられなくても検索は停止されます.
    グローバルスコープと関数スコープ
    グローバルスコープと関数スコープはどうやって理解できますか?var宣言変数を使用すると、関数外で宣言すれば、グローバル変数です.どの関数も使用できます.これがグローバルスコープ検索です.関数内でvar宣言変数を使用すると、関数のスコープ検索です.関数の内部のみアクセスできます.外部は次のようなセグメントコードではアクセスできません.
    var a = 12; //          
     function myFunction() {
       console.log(a); // alerts 12
       var b = 13;
       if(true) {
         var c = 14; //         
         alert(b); // alerts 13
       }
       alert(c); // alerts 14
     }
     myFunction();
     alert(b); // alerts undefined
    なぜb変数がアクセスできないのですか?変数bは関数内で宣言されているので、関数が実行された後、ゴミデータ回収メカニズムが存在するため、エンジンは関数の実行が完了したと判断し、変数は破壊されるべきです.
    関数内でbマークを書き忘れたら、varを書き忘れたら、エンジンは頭が良くなります.関数外の大域作用領域で変数bを自動的に宣言します.そうすると、関数外でb変数(大域作用領域)にアクセスできます.
    したがって、varを使って声明を出す時に、誤ったらグローバルスコープの変数を宣言します.もっと悪い場合は同じ名前の変数を汚染する可能性があります.したがって、BUGは検索しにくいです.
    以下のこの例は、開発者がよく発生する問題であり、i変数は外部作用領域(関数またはグローバル作用領域)に結合され、外部作用領域全体を汚染することができる.
    for(var i=0;i<10;i++){
    	console.log(i); //    1 9
    }
    console.log(i);//10
    ブロックレベルのスコープ
    幸いにes 6はletを導入して、var宣言変数のいくつかの問題を回避しました.変数と関数は所所の作用領域だけでなく、あるコードブロック(通常は「...」内部)に属してもいいです.ブロックレベルの作用領域で定義された変数は、ブロックレベルが域外ではアクセスできないことを強調する必要があります.
    let a = 12; //      ,    
    function myFunction() {
       console.log(a); // alerts 12
       let b = 13;
       if(true) {
         let c = 14; // this is NOT accessible throughout the function!
         alert(b); // alerts 13
       }
       alert(c); // alerts undefined  {} ,      
     }
     myFunction();
     alert(b); // alerts undefined  {} ,      
    for循環体では、varとletを使用した違いがより明確であり、一つは大域作用域での検索変数であり、一つはブロックレベルの作用域で変数を検索することであり、ブロックレベルの作用領域は一回ごとに実行されると、一つの作用領域が発生する.まずforサイクルにおいて、var宣言変数を使って、次のようなセグメントコードで示します.
    for(var i=0;i<5;i++){
    	setTimeout(function() {
    		console.log(i); 
    	}, 1000);
    }
    //    5 5 5 5 5
    JavaScriptは単一スレッドであるため、イベント循環機構の存在(イベント循環メカニズムがよくわからないので、「JavaScript基礎」を確認してもいいです.JavaScriptは本当にJava Scriptが何かを知っていますか?」)、メインスレッドがforループを実行した後、SetTimeOut内の関数が実行されます.forループが完了すると、iの変数は自然に5に等しくなりますので、setTimeOutは内部関数を実行する時、i変数の値を探して、5を出力します.図に示すように変数はパスを探します.
    letをvarに置き換えると、どのような結果が出力されますか?
    for(let i=0;i<5;i++){
    	setTimeout(function() {
    		console.log(i);
    	}, 1000);
    }
    //    0,1,2,3,4
    ブロックレベルの作用領域の存在により、循環毎に、循環体ブロックレベルの作用領域が発生し、結果として予想される出力が達成される.図に示すように変数はパスを探します.
    varとletの比較
    比較項目
    let
    var
    変数を宣言


    リリースできます


    昇進できる

    定義の繰り返しチェック

    ブロックスコープに使用できます.

    繰り返し定義変数の問題
    同じスコープでvarを使って変数を繰り返し定義します.後者は元の宣言の変数の値を上書きします.次のセグメントコードで示します.
    var a = 0;
    var a = 1;
    alert(a); // alerts 1
    function myFunction() {
     var b = 2;
     var b = 3;
     alert(b); // alerts 3
    }
    myFunction();
    letを使って同じ作用領域で変数を繰り返し定義すると、SyntxErrerのエラーが発生します.次のようにセグメントコードで示します.
    let a = 0;
    let a = 1; // SyntaxError
    function myFunction() {
     let b = 2;
     let b = 3; // SyntaxError
     if(true) {
    	let c = 4;
    	let c = 5; // SyntaxError
     }
    }
    myFunction();
    ネストされたスコープ内で変数を再定義すると、変数名は同じですが、同じ変数ではなく、次のようなセグメントコードが示されます.
    var a = 1;
    let b = 2;
    function myFunction() {
    	var a = 3; // different variable
    	let b = 4; // different variable
    	if(true) {
    	  var a = 5; // overwritten
    	  let b = 6; // different variable
    	  console.log(a); // 5
    	  console.log(b); // 6
    }
    	  console.log(a); // 5
    	  console.log(b); // 4
    }
    myFunction();
    console.log(a);
    console.log(b);
    概念を高める問題
    JavaScriptを初めて学んだ学生は、直観的にコンパイラが上から次の行に実行されると思っていますが、正確ではないです.関数宣言と変数宣言はアップグレードされます.関数はまずアップグレードされます.
    まず、次のセグメント関数のコードを見ます.
    bookName("ES8 Concepts");
    function bookName(name) {
    	console.log("I'm reading " + name);//I'm reading ES8 Concepts
    }
    正常出力は、関数が実行文にアップグレードされます.下記のコードを見て、変数の方式で関数を宣言します.
    bookName("ES8 Concepts"); //TypeError: bookName is not a function
    var bookName = function(name) {
    	console.log("I'm reading " + name);
    }
    なぜですか?JavaScriptエンジンは先に関数を昇格させ、変数宣言を昇格させるだけで、エンジンは上記のコードに対してこのように調整されます.コードは以下の通りです.
    var bookName; //           
    bookName("ES8 Concepts"); // bookName is not function 
    // because bookName is undefined
    bookName = function(name) { //          
    	console.log("I'm reading " + name);
    }
    もしletを使ってvar宣言関数を交替したら?どのようなヒント出力がありますか?次のセグメントコードに示します.
    bookName("ES8 Concepts"); // ReferenceError: bookName is not defined
    let bookName = function(name) {
    	console.log("I'm reading " + name);
    }
    ここからlet宣言を使用する変数は変数宣言の昇格を生じないことが分かります.このような利点は、上から下までの慣例に従ってコードを書いて、問題が発生する検索しにくい問題をできるだけ上げないようにします.
    小節
    今日の文章はここまでです.letはvarの進化版とも言えます.奇異な問題を避けるために、大多数の高級言語に従ってコードを書くことができます.ほとんどの場合、let声明を使って量を変えて、コードをよりメンテナンスしやすく使うべきです.
    本論文の一部の内容は参:『あなたの知らないJavaScript』です.
    もっと素晴らしい内容があります.微信に注目してください.