(1) Skop
Skop pembolehubah ialah kawasan pembolehubah yang ditakrifkan dalam kod sumber program.
1. Skop leksikal digunakan dalam JS
Pembolehubah yang tidak diisytiharkan dalam mana-mana fungsi (var diketepikan dalam fungsi juga dianggap global) dipanggil pembolehubah global (skop global)
Pembolehubah yang diisytiharkan dalam fungsi mempunyai skop fungsi dan merupakan pembolehubah setempat
Pembolehubah setempat mempunyai keutamaan yang lebih tinggi daripada pembolehubah global
Mengabaikan var dalam fungsi akan menjejaskan pembolehubah global, kerana ia sebenarnya telah ditulis semula menjadi pembolehubah global
Skop fungsi, iaitu, fungsi ialah unit asas skop js tidak mempunyai skop peringkat blok seperti c/c, seperti jika untuk, dsb.
Sudah tentu, fungsi tertib tinggi juga digunakan dalam js, yang sebenarnya boleh difahami sebagai fungsi bersarang
Selepas test1(), fungsi luar akan dipanggil, dan fungsi dalam akan dikembalikan Kemudian continue(), dan fungsi dalam akan dipanggil dan dilaksanakan dengan sewajarnya, jadi "satu"
akan menjadi output.Fungsi bersarang melibatkan penutupan, yang akan kita bincangkan kemudian di sini fungsi dalaman boleh mengakses nama pembolehubah yang diisytiharkan dalam fungsi luar, yang melibatkan mekanisme rantai skop
2. Pengisytiharan dalam JS terlebih dahulu
Skop fungsi dalam js bermakna semua pembolehubah yang diisytiharkan dalam fungsi sentiasa kelihatan dalam badan fungsi. Selain itu, pembolehubah boleh digunakan sebelum ia diisytiharkan Keadaan ini dipanggil angkat
petua: Pengisytiharan terlebih dahulu dilakukan apabila enjin js diprasusun Fenomena pengisytiharan terlebih dahulu berlaku sebelum kod dilaksanakan
Contohnya
Perkara di atas mencapai kesan berikut
Cuba alih keluar var lagi? Ini ialah nama dalam fungsi yang telah menjadi pembolehubah global, jadi ia tidak lagi tidak ditentukan
3. Perlu diingat bahawa tiada satu pun daripada parameter yang dinyatakan di atas lulus Bagaimana jika ujian mempunyai parameter?
Seperti yang dinyatakan sebelum ini, jenis asas diluluskan mengikut nilai, jadi nama yang diluluskan ke dalam ujian sebenarnya hanyalah salinan ini dikosongkan selepas fungsi kembali.
Jangan fikir nama="two" dalam fungsi menukar nama global, kerana ia adalah dua nama bebas
(2) Rantai skop
Fungsi lanjutan yang dinyatakan di atas melibatkan rantai skop
1. Perkenalkan perenggan besar untuk menerangkan:
Setiap bahagian kod JavaScript (kod atau fungsi global) mempunyai rantaian skop yang dikaitkan dengannya.
Rantai skop ini ialah senarai atau senarai objek yang dipautkan Kumpulan objek ini mentakrifkan pembolehubah "dalam skop" dalam kod ini.
Apabila js perlu mencari nilai pembolehubah x (proses ini dipanggil resolusi pembolehubah), ia akan bermula dari objek pertama dalam rantaian Jika objek ini mempunyai atribut bernama x, maka nilai atribut ini adalah digunakan secara langsung. Jika tiada atribut bernama x dalam objek pertama, js akan terus mencari objek seterusnya dalam rantai. Jika objek kedua masih tidak mempunyai atribut bernama x, ia akan terus mencari yang seterusnya, dan seterusnya. Jika tiada objek dalam rantai skop mengandungi atribut x, maka x dianggap tidak wujud dalam rantai skop kod ini, dan akhirnya pengecualian ReferenceError dilemparkan.
2. Contoh rangkaian skop:
Dalam kod peringkat atas js (iaitu, kod yang tidak termasuk sebarang definisi fungsi), rantai skop terdiri daripada objek global.
Dalam badan fungsi yang tidak mengandungi sarang, terdapat dua objek pada rantai skop Yang pertama ialah objek yang mentakrifkan parameter fungsi dan pembolehubah setempat, dan yang kedua ialah objek global.
Dalam badan fungsi bersarang, terdapat sekurang-kurangnya tiga objek dalam skop.
3. Peraturan penciptaan rantai skop:
Apabila fungsi ditakrifkan (perhatikan, ia bermula apabila ia ditakrifkan), ia sebenarnya menjimatkan rantai skop.
Apabila fungsi ini dipanggil, ia mencipta objek baharu untuk menyimpan parameter atau pembolehubah setempatnya, menambahkan objek pada rantai skop tersebut dan mencipta perwakilan baharu yang lebih panjang bagi skop panggilan fungsi "rantai".
Untuk fungsi bersarang, keadaan berubah lagi: setiap kali fungsi luaran dipanggil, fungsi dalaman akan ditakrifkan semula semula. Kerana setiap kali fungsi luaran dipanggil, rantai skop adalah berbeza. Fungsi dalaman perlu berbeza secara halus setiap kali ia ditakrifkan - kod fungsi dalam adalah sama setiap kali fungsi luar dipanggil, dan rantai skop yang dikaitkan dengan kod ini juga berbeza.
(petua: Fahami tiga perkara di atas dengan baik dan ingat. Sebaik-baiknya sebut dengan perkataan anda sendiri, jika tidak, anda perlu menghafalnya, kerana penemuduga akan bertanya terus kepada anda: Sila terangkan rantaian skop.. . )
Contoh praktikal rantaian skop:
Di atas ialah fungsi bersarang, dengan itu mesti ada tiga objek dalam rantai skop
Kemudian apabila memanggil, anda perlu mencari nilai nama, hanya cari
Apabila test1() berjaya dipanggil, tertibnya ialah test1()->test()-> kerana nilai tiga nama ditemui pada test1(), carian selesai dan mengembalikan
Apabila test1() berjaya dipanggil, susunannya ialah test2()->test()->tetingkap objek global Oleh kerana nilai nama tidak ditemui pada test2(), kami mencarinya dalam test(. ) dan cari jika nilai nama ialah dua, carian akan selesai dan mengembalikan
Contoh lain ialah kadangkala kita melakukan kesilapan dan sering ditipu semasa temuduga.
为什么?
根据作用域链中变量的寻找规则:
这里有一个函数,它是匿名函数,既然是函数,那就在作用域链上具有一个对象,这个函数里边使用到了变量i,它自然会在作用域上寻找它.
查找顺序是 这个匿名函数 -->外部的函数buttonInit() -->全局对象window
匿名函数中找不到i,自然跑到了buttonInit(), ok,在for中找到了,
这时注册事件已经结束了,不要以为它会一个一个把i放下来,因为函数作用域之内的变量对作用域内是一直可见的,就是说会保持到最后的状态
当匿名函数要使用i的时候, 注册事件完了, i已经变成了4, 所以都是Button4
那怎么解决呢?
给它传值进去吧, 每次循环时, 再使用一个匿名函数, 把for里边的i传进去, 匿名函数的规则如代码