cari

Rumah  >  Soal Jawab  >  teks badan

javascript - Memahami penutupan? Dapatkan penjelasan.

function f1(){//2、找到 f1 函数,执行。
    var n=999;//3、给变量 n 赋值。
    nAdd=function(){n+=1}//9、找到 nAdd ,匿名函数内没有变量 n ,需要去上层查找,n = 999 +1。
    function f2(){//5、找到 f2 函数,执行。
        alert(n);//6、执行动作。
    }
    console.log(n);//新加上,测试,不参与执行步骤。
    return f2;//4、返回 f2 函数,需要寻找 f2 函数。
}
var result=f1();//1、将 f1函数的返回值赋值给 result 变量,result 也变成函数,需要寻找f1函数。
result(); //7、第一次执行 result 函数,将步骤 6 的执行动作(步骤 6)结果输出,n 等于 999。
nAdd();//8、执行 f1 函数里的全局变量函数 nAdd ,需要寻找 nAdd 函数。
result(); //10、第二次执行 result 函数,将步骤 5 的执行动作(步骤 6)结果输出,此时 n 等于 1000,因为第一次执行 result 函数时,查找了上层的作用域,n 是 999。
nAdd();//11、如果再执行 nAdd 函数,此时 nAdd 这个函数里的 n 是 1000,而 f1 函数的 n 还是 999,也就是说 f1 的变量 n 和 nAdd 的 n 是两个作用域不同的同名变量。
result(); 
f1();//新加上,测试

/*结果
控制台输出:999
弹窗:999
弹窗:1000
弹窗:1001
控制台输出:999
*/

Saya ingin bertanya kepada senior untuk melihat sama ada pemahaman ini betul.
Supplement: Bolehkah difahami bahawa apabila penutupan dilaksanakan buat kali pertama, ia perlu mencari pembolehubah di lapisan atas Selepas menemuinya, nilai pembolehubah di lapisan atas menjadi nilai pembolehubah sub-fungsi . Pada masa hadapan, tidak perlu mencari di lapisan atas kerana ia telah diwarisi semasa pelaksanaan pertama dan menjadi milik anda.
Rasanya agak kucar-kacir. . .
(penutup muka

-----------------------Ditambah lagi----------------------- -
Semakin saya melihatnya, semakin mengelirukan.
Kemudian ia menjadi kucar-kacir.
Berdasarkan hasil keluaran, keluaran konsol pertama dan keluaran konsol terakhir, n bagi f1 adalah tidak berubah.
Tetapi tidakkah subfungsi boleh membaca pembolehubah antara satu sama lain? Mengapakah ungkapan nAdd mempengaruhi n f2?

高洛峰高洛峰2780 hari yang lalu491

membalas semua(4)saya akan balas

  • 某草草

    某草草2017-05-18 10:51:50

    function f1(){
        var n=999;
        nAdd=function(){n+=1}
        function f2(){
            alert(n);
        }
        console.log(n);
        return f2;
    }
    var result=f1();
    result(); 
    nAdd();
    result();
    nAdd();
    result(); 
    var b = f1();//新加上,测试
    

    Pada masa ini, hasil b dan n tidak sama
    b dan n dalam nTambah adalah sama.

    balas
    0
  • PHP中文网

    PHP中文网2017-05-18 10:51:50

    Saya mempunyai soalan yang sama, jadi saya menyalin jawapan saya dan menambah beberapa lagi.

    1. var result=f1(): Fungsi f1 mengembalikan fungsi f2 var result=f1():f1函数返回了f2函数
      把返回的f2函数赋值给result全局变量,(f2的作用域链保存到result全局变量中)

    2. result():调用result(),这就形成闭包:有权访问另外一个函数作用域中的变量
      因为在f2中的作用域引用了f1中的n这个局部变量,当f1执行完毕后,垃圾回收机制发现n变量还在被result中引用所以垃圾回收机制不会把n回收释放。
      以至于n一直保存在result作用域链中。result的作用域链正常能访问f1中的局部变量n,形成闭包。

    3. nAdd():nAdd没有写var所以nAdd是全局变量,在调用nAdd()和result()是一样的都会形成闭包,匿名函数function(){n+=1}的作用域链中有n这个局部变量,所以当nAdd=funtion(){n+=1}时,这个匿名函数的作用域链保存到了全局变量nAdd形成闭包,调用nAdd()作用域链中找到f1局部变量n=999,n+1=1000。

    4. result() Berikan fungsi f2 yang dikembalikan kepada pembolehubah global hasil,

      (rantaian skop f2 disimpan pada pembolehubah global hasil)
    5. hasil(): Hasil panggilan(), yang membentuk penutupan:
    6. Mempunyai hak untuk mengakses pembolehubah dalam skop fungsi lain

      Kerana skop dalam f2 merujuk kepada skop dalam f1 n ialah pembolehubah tempatan Apabila f1 dilaksanakan, mekanisme kutipan sampah mendapati pembolehubah n masih dirujuk dalam hasil, jadi mekanisme kutipan sampah tidak akan melepaskan n.
    7. Supaya n sentiasa disimpan dalam rantaian skop hasil. Rantaian skop hasil biasanya boleh mengakses pembolehubah tempatan n dalam f1, membentuk penutupan.
    8. nAdd(): nAdd tidak menulis var, jadi nAdd ialah pembolehubah global Memanggil nAdd() dan result() adalah sama dan akan membentuk penutupan fungsi tanpa nama(){. n+=1} Terdapat pembolehubah tempatan n dalam rantaian skop, jadi apabila nAdd=function(){n+=1}, rantaian skop fungsi tanpa nama ini disimpan ke pembolehubah global nAdd untuk membentuk penutupan, yang ditemui dalam rantai skop dengan memanggil nAdd() f1 pembolehubah tempatan n=999, n+1=1000.

    hasil(): hasil() mengeluarkan 1000

    nTambah(); Ulang langkah ketiga n+1 = 1001

    🎜hasil(); Ulangi langkah keempat dan keluarkan n🎜🎜 🎜🎜f1(); Tiada penutupan terbentuk apabila f1 dipanggil, n sentiasa 999, kerana n dimusnahkan oleh mekanisme pengumpulan sampah selepas setiap pelaksanaan f1, jadi var n=999 dipanggil semula di sini; Dah 999🎜🎜 🎜 🎜🎜Mengapakah ungkapan nAdd mempengaruhi n f2? 🎜🎜 Kerana penutupan, n tidak pernah dimusnahkan nAdd() juga membentuk penutupan dan menukar nilai n, jadi result() dipanggil semula kemudiannya dan kitar semula telah +1, jadi ia akan menjadi Pengaruh. 🎜 Akhirnya, tiada penutupan apabila f1() dipanggil, dan n telah dimusnahkan sebelum ini. Jadi ia sentiasa mengeluarkan a=999;🎜 🎜🎜Ini sekadar pemahaman saya, jika ada salah silap maklumkan🎜🎜

    balas
    0
  • 黄舟

    黄舟2017-05-18 10:51:50

    Saya cadangkan anda membaca ini
    http://www.ruanyifeng.com/blo...
    Ia diterangkan dengan lebih jelas

    balas
    0
  • 曾经蜡笔没有小新

    曾经蜡笔没有小新2017-05-18 10:51:50

    Terlalu rumit untuk dikatakan

    Penutupan ini menggunakan ciri skop statik js untuk mencapai kesan ini

    function f1(){
        var n=999;// 这里标识n 为代号 n1
        nAdd=function(){n+=1}+1。
        function f2(){
            alert(n);
        }
        console.log(n);
        return f2;
    }
    var result=f1();
    result(); 
    nAdd();
    result(); 
    nAdd();
    result(); 
    f1();
    

    Panggilan pertama untuk keputusan():

    alert(n); sedang mencari n1

    nAdd(); juga menambah nilai n1

    Begitu juga dengan yang di belakang

    Dan yang terakhir f1();

    Apabila berjalan, var n = 999; memberikan nilai kepada n1
    n ​​console.log(n) juga n1, jadi nilai yang dicetak ialah 999

    .

    Contoh anda agak mudah Anda boleh melihat contoh yang kompleks (fokus pada penerangan skop statik):
    skop statik

    .

    balas
    0
  • Batalbalas