関数のスコープを詳しく説明する


一、変数の昇格
1、変数 var window ( window )
console.log(a); // undefined     ,     
console.log(window.a, 'a' in window) // undefined true
var a = 5;
console.log(a); // 5
console.log(window.a, 'a' in window) // 5 true
var , , window.b=9
console.log(b)  // Uncaught ReferenceError: b is not defined
console.log(window.b, 'b' in window) // undefined false
b = 9;
console.log(b) // 9
console.log(window.b, 'b' in window)  // 9 true
var c = d = 10;
var c=10;
d=10;
2、関数function var :function , ( ) ,function , , ,
var f1 = () => {
    console.log(2)
}
function f1() {
    console.log(1)
}
f1(); // 2    function f1       
, var,
console.log(a, b);  // undefined undefined
var a = 12, b = 12;
function fn() {
    console.log(a, b); // undefined 12  b  var      
    
    //   b  ,   window.b=13,          b          window.b      ,  b     13
    var a = b = 13; 
    console.log(a, b) // 13 13
}
fn();
console.log(a, b); // 12 13
  • 条件文のvar変数は依然として変数を上げます.
  • 条件文の関数も変数が上昇しますが、ステートメントだけでは
  • は定義されません.
  • 条件が成立すれば、条件の最初のステップは、先に事前チェックをするときに、定義されていない関数だけを定義する
  • である.
    console.log(c); // undefined
    console.log(f1); // undefined             ,   
    if (1) {
        console.log(f1); // funciton f1(){}        ,       ,           (         ,    )
        var c = 2;
        function f1() {
            console.log('f1');
        }
    }
    console.log(f1); // funciton f1(){}
    console.log(c);  // 2
    , if
    console.log(c); // undefined
    console.log(f1); // undefined             ,   
    if (0) {
        console.log(f1);
        var c = 2;
        function f1() {
            console.log('f1');
        }
    }
    console.log(f1); // undefined
    console.log(c);  // undefined
    次の問題
    f = function () { return true }
    g = function () { return false }
    ~function () {
        if (g() && [] == ![]) {  //  4       [] == ![] true
            f = function () { return false }
            function g() {
                return true
            }
        }
    }();
    console.log('f()', f())
    console.log('g()', g())
    : , , , ,if ,function g , ; if g() && [] == ![] , g undefined 変換して、if判定条件の中でg()をf()に変えます.
    f = function () { return true }
    g = function () { return false }
    ~function () {
        if (f() && [] == ![]) {  //  4 [] == ![] true
            f = function () { return false }
            function g() {
                return true
            }
        }
    }();
    console.log('f()', f()) // false
    console.log('g()', g()) // false
    : f f , , if f() f, true; if , f (return false), g , g二、名前を変更する
    1、varとfunctionの名前が重複して上書きされます.
    ff() // ff
    var ff =12;
    ff()  //        ff 12,    
    function ff(){
        console.log('ff')
    }
    ff() //        ff 12,    
    2、jsはとても怠惰で、もしすでに声明してしかも価値を賦課するならば、更に賦課を声明して、再び価値を賦課するだけです.
    fn();  // 4
    function fn() { console.log(1) }
    fn(); // 4
    function fn() { console.log(2) }
    fn(); // 4
    var fn = 2;
    fn(); // not function error
    function fn() { console.log(3) }
    fn(); // not function error
    function fn() { console.log(4) }
    fn(); // not function error
    三、let const
    1、let const window
    console.log(l); // error
    let l = 5;
    console.log(window.l) // undefined
    console.log('l' in window) // false
    2、ブラウザが実行する前に、letを使用した変数を検出します.エラーが発生します.
    let a=12;
    a=12;
    console.log(a) //               ,       
    let a=13; //   ,     
    var a=13; //   
    実は第一行で間違えました.
    var b=12; //   
    let b=13; 
    3、一時性死区
    let a = 10, b = 10;
    let fn = function () {
        console.log(a) //               let a
        console.log(b) // 10
        let a = b = 20
        console.log(a) // 20
        console.log(b) // 20
    }
    fn()
    console.log(a, b) // 10 20
    var a = 12;
    if (true) {  // let   {}     
        console.log(a);  //   
        let a = 13;
        console.log(a) // 13
    }
    console.log(a)  // 12
    四、スコープ
    1、関数の上位のスコープは誰ですか?実行時の位置は関係なく、その関数が定義した位置と関係があります.
    var a = 12;
    function fn2() {
        console.log(a)  // 12
    }
    function sum() {
        var a = 20;
        fn2();
        console.log(a); //20
    }
    sum();
    2、クローズド
    var n = 10;
    function fn3() {
        var n = 20;
        function fn4() {
            n++;
            console.log(n)
        }
        fn4();
        return fn4;
    }
    var x = fn3(); // 21
    x(); //22
    x(); //23
    console.log(n); //10
    `ヒープメモリ:参照データタイプの値を記憶する(対象:キーパッドのペア、関数:コード文字列)
  • )ヒープメモリは、参照ヒープメモリアドレスの変数割当値をnull
  • とする.
  • スタックメモリ:jsコード実行環境を提供し、基本タイプ値
  • を記憶する.
  • )スタックメモリは、関数が実行されると、形成されたプライベートスコープが自動的に解放され、
  • しかし、スタックメモリにある内容がスタックメモリ以外の変数によって引用された場合、
  • を解放することはできません.
  • )グローバルスタックメモリは、ページが閉じているだけで
  • を解放することができます.
    `
    五、軽蔑問題 , ,
    var a = 12, b = 13, c = 14;
    function fn(a) {
        //              a=12
        //        var b;
        // var function          
        console.log(a, b, c) // 12 undefined 14
        var b = c = a = 20;
        console.log(a, b, c) // 20 20 20
    }
    fn(a); //     12
    console.log(a, b, c) // 12 13 20
    派生して
    var arr = [12, 23];
    function fn1(arr) {
        console.log(arr); // [12, 23]
        //     ,        ,       arr[0]   ,  arr  [100.23]
        arr[0] = 100; 
        arr = [100];
        arr[0] = 0;
        console.log(arr); // [0]
    }
    fn1(arr);
    console.log(arr); // [100,23]