[ydkjsy]Scope & Closures-3-The Scope Chain


語彙の範囲は何ですか.コードに記述されたものを基準とし、どこで宣言されたかを基準として範囲を指定することを指す.知っているメリットは、エラーを減らし、利用することができますか?

スキャンチェーンとは、他のスキャンチェーンに重複するスキャンチェーン間の接続を指す.

"Lookup" Is (Mostly) Conceptual


現在のファイルで宣言されていない変数を参照すると、実行時の他のファイルが実際に共有されているグローバルスキャンに変数を宣言する可能性があるため、必ずしもエラーではありません.
最終的には、アクセス可能なパケットで正しく宣言されているかどうかは、実行時によって異なります.
最初に宣言されていない変数への参照は、ファイルのコンパイル時、他の関連ファイルのコンパイル時、または実行時の開始前にグローバルスキャンでチェックされ、色は指定されません.
このクエリは変数ごとに最大1回しか必要ありません.実行時にMABLE色を変更できないため

Shadowing


普通は同じ顕微鏡に同じ名前は書かない.
var studentName = "Suzy";

function printStudent(studentName) {
    studentName = studentName.toUpperCase();
    console.log(studentName);
}//lookup의 방식을 떠올려라.

printStudent("Frank");
// FRANK

printStudent(studentName);
// SUZY

console.log(studentName);
// Suzy
ここで、関数のパラメータstudentNameにより、グローバルstudentNameは影化され、関数内部では利用できない.

Global Unshadowing Trick


使わないでください.グローバルオブジェクトwindowのpropertyを使用してロードします.
var studentName = "Suzy";

function printStudent(studentName) {
    console.log(studentName);
    console.log(window.studentName);
}

printStudent("Frank");
// "Frank"
// "Suzy"
実際の変数にアクセスするgetter/setterと見なすことができますが、実際には、グローバルオブジェクトを定義してpropertyを作成することでグローバル変数を作成できます.この方法にはいくつかの制限があります.グローバル変数の場合、varまたはfunctionと宣言された場合.
var one = 1;
let notOne = 2;
const notTwo = 3;
class notThree {}

console.log(window.one);       // 1
console.log(window.notOne);    // undefined
console.log(window.notTwo);    // undefined
console.log(window.notThree);  // undefined
var special = 42;

function lookingFor(special) {
    // The identifier `special` (parameter) in this
    // scope is shadowed inside keepLooking(), and
    // is thus inaccessible from that scope.

    function keepLooking() {
        var special = 3.141592;
        console.log(special);
        console.log(window.special);
    }

    keepLooking();
}

lookingFor(112358132134);
// 3.141592
// 42

Copying Is Not Accessing

var special = 42;

function lookingFor(special) {
    var another = {
        special: special
    };

    function keepLooking() {
        var special = 3.141592;
        console.log(special);
        console.log(another.special);  // Ooo, tricky!
        console.log(window.special);
    }

    keepLooking();
}

lookingFor(112358132134);
// 3.141592
// 112358132134
// 42

Illegal Shadowing


letは、varが関数の内部にない限りvarをシャドウすることができます.
function something() {
    var special = "JavaScript";
    {
        let special = 42;   // totally fine shadowing
        // ..
    }
}
function another() {
    // ..
    {
        let special = "JavaScript";
        {
            var special = "JavaScript";
            // ^^^ Syntax Error cross the boundary
        }
    }
}

Function Name Scope


関数式では、関数自体はネストされません.
ここで、ofTheTeacherは、関数内部の識別子として宣言される.(実際には関数スキャンではありません)
var askQuestion = function ofTheTeacher() {
    console.log(ofTheTeacher);
};

askQuestion();
// function ofTheTeacher()...

console.log(ofTheTeacher);
// ReferenceError: ofTheTeacher is not defined
厳格モードでは、この識別子が再割り当てされた場合、TypeErrorとなる.非厳格モードでも自動的に失敗します.
匿名関数の場合、2つの範囲の名前識別子には影響しません.

Arrow Functions


語彙的には匿名です.推測するしかない.以下は様々なタイプです.
() => 42;

id => id.toUpperCase();

(id,name) => ({ id, name });

(...args) => {
    return args[args.length - 1];
};
一般関数と同じLexicalScopeを持つ.