Rumah > hujung hadapan web > tutorial js > Asas JavaScript (6) Penutupan Ungkapan Fungsi_Kemahiran Javascript

Asas JavaScript (6) Penutupan Ungkapan Fungsi_Kemahiran Javascript

WBOY
Lepaskan: 2016-05-16 15:26:22
asal
978 orang telah melayarinya

Sebenarnya, sebab utama js menyokong penutupan fungsi adalah kerana js memerlukan fungsi untuk dapat menyimpan data. Data yang disimpan di sini ialah hanya nilai pembolehubah dalam fungsi akan disimpan selepas fungsi tamat. Mengenai mengapa js perlu dapat menyimpan data dalam fungsi, iaitu js ialah bahasa berfungsi. Menyimpan data dalam fungsi adalah ciri khas bahasa berfungsi.

Semak semula tiga kaedah mentakrifkan fungsi yang diperkenalkan sebelum ini

functiosu(numnumreturnunum//Takrifan sintaks pengisytiharan fungsi
vasufunction(numnum)returnunum}//Takrif ungkapan fungsi
vasuneFunction("num""num""returnunum")//Functio constructor

Sebelum menganalisis penutupan, mari kita lihat dahulu kesilapan biasa dalam mentakrif dan memanggil fungsi.

Contoh 1:

sayHi(); //错误:函数还不存在
var sayHi = function () {
  alert("test");
};
Salin selepas log masuk

Contoh 2:

if (true) {
  function sayHi() {
    alert("1");
  }
} else {
  function sayHi() {
    alert("2");
  }
}
sayHi();//打印结果并不是我们想要的
Salin selepas log masuk

Contoh 3:

var fun1 = function fun2() {
  alert("test");
}
fun2();//错误:函数还不存在
Salin selepas log masuk

Dalam Contoh 1, kita tidak boleh memanggil fungsi sebelum mentakrifkannya menggunakan sintaks deklaratif fungsi. Penyelesaian:

1 Jika anda menggunakan ungkapan fungsi untuk mentakrifkan fungsi, ia perlu dipanggil selepas ungkapan itu ditakrifkan.

var sayHi = function () {
  alert("test");
};
sayHi()
Salin selepas log masuk

2. Gunakan pengisytiharan fungsi. (Di sini enjin penyemak imbas akan mempromosikan pengisytiharan fungsi dan membaca pengisytiharan fungsi sebelum semua kod dilaksanakan)

sayHi(); 
function sayHi () {
  alert("test");
};
Salin selepas log masuk

Dalam Contoh 2, hasil jangkaan kami sepatutnya mencetak 1, tetapi hasil sebenar ialah mencetak 2.

if (true) {
  function sayHi() {
   alert("1");
  }
  } else {
  function sayHi() {
   alert("2");
  }
}
sayHi();//打印结果并不是我们想要的
Salin selepas log masuk

Mengapa ini berlaku? Kerana promosi pengisytiharan fungsi, penyemak imbas tidak akan menilai keadaan if semasa pra-penghuraian, dan secara langsung menimpa yang pertama apabila menghuraikan definisi fungsi kedua.

Penyelesaian:

var sayHi;
if (true) {
  sayHi = function () {
   alert("1");
  }
  } else {
  sayHi = function () {
   alert("2");
  }
}
sayHi();
Salin selepas log masuk

Dalam Contoh 3, kami mendapati bahawa kami hanya boleh menggunakan fun1() untuk memanggil, tetapi bukan fun2().

Dari pemahaman saya sendiri, saya tidak tahu sebab sebenar. Tiada maklumat ditemui.

Kerana 1: function fun3() { }; adalah bersamaan dengan var fun3 = function fun3() { };

Jadi anda hanya boleh menggunakan fun1() untuk memanggil, tetapi bukan fun2().

Sebenarnya, saya masih ada soalan di sini? Jika sesiapa tahu, sila beritahu saya.

Memandangkan fun2 tidak boleh dipanggil dari luar, mengapa ia boleh dipanggil dari dalam fungsi? Walaupun saya masih tidak boleh mendapatkan fun1 dalam penyahpepijat.

Baiklah, mari kita hangat dengan tiga soalan di atas. Mari kita teruskan dengan topik "penutupan" hari ini.

1. Apakah itu penutupan?

Definisi: Ia ialah fungsi yang mempunyai akses kepada pembolehubah dalam skop fungsi lain

Mari mulakan dengan fungsi contoh:

Contoh 1:

function fun() {
  var a = "张三";
}
fun();//在我们执行完后,变量a就被标记为销毁了
Salin selepas log masuk
Contoh 2:

function fun() {
  var a = "张三";
  return function () {
    alert("test");
  }
}
var f = fun();//同样,在我们执行完后,变量a就被标记为销毁了
Salin selepas log masuk
Contoh 3:

function fun() {
  var a = "张三";
  return function () {
    alert(a);
  }
}
var f = fun();//【现在情况发生变化了,如果a被销毁,显然f被调用的话就不能访问到变量a的值了】
f();//【然后变量a的值正常的被访问到了】
//这就是闭包,当函数A 返回的函数B 里面使用到了函数A的变量,那么函数B就使用了闭包。
示例:
function fun() {
  var a = "张三";
  return function () {
   alert(a);
  }
}
var f = fun();//【现在情况发生变化了,如果a被销毁,显然f被调用的话就不能访问到变量a的值了】
f();//【然后变量a的值正常的被访问到了】
Salin selepas log masuk
Jelas sekali, penyalahgunaan penutupan akan meningkatkan penggunaan memori. Oleh itu, cuba untuk tidak menggunakan penutupan melainkan terdapat keadaan khusus. Jika digunakan, ingat untuk menetapkan rujukan null secara manual supaya memori boleh dikitar semula f = null ;

Ilustrasi: (Pelajar yang tidak memahami rantaian skop, sila baca artikel sebelum ini Skop dan Rantaian Skop dahulu)

2. Apakah fungsi tanpa nama? (Sekadar menerangkan konsep)

Contohnya: (iaitu fungsi tanpa nama)

Mengenai fenomena aneh ini apabila nilai pulangan fungsi dalam objek ialah fungsi tanpa nama

Sebelum menerangkan, sila bersihkan kepala anda dahulu dan jangan bertambah keliru semasa anda membaca. Jika anda keliru, abaikan sahaja perkara berikut.

var name1 = "张三";
var obj = {
  name1: "李四",      
  fun2: function () {
    alert(this.name1);
  },
  fun3: function () {
    return function () {
      alert(this.name1);
    }
  }
}
Salin selepas log masuk
obj.fun2();//Hasil cetakan "李思" adalah seperti yang dijangkakan.
obj.fun3()();//Oleh kerana apa yang dikembalikan di sini ialah fungsi, kita perlu menambah sepasang () untuk memanggilnya. Hasil cetakan ialah "Zhang San", yang tidak dijangka.

//Ia benar-benar mengelirukan. Apakah maksud ini kepada keadaan keseluruhan?
Kami berkata sebelum ini bahawa "mana-mana objek yang mengklik kaedah, ini ialah objek", kemudian obj.fun3()() kami mencetak "Zhang San", yang bermaksud ini melaksanakan skop global.

Kita mungkin faham sebabnya dengan melihat contoh di bawah.

Mari menguraikan obj.fun3()(). Mula-mula, obj.fun3() mengembalikan fungsi tanpa nama kepada skop tetingkap, dan kemudian memanggilnya untuk menunjuk ke tetingkap. (Saya rasa penjelasannya agak terpaksa, dan saya tidak tahu sama ada betul atau tidak. Beginilah cara saya memahaminya buat masa ini)

Punca pembentukan penutupan: masalah pelepasan ingatan

Secara amnya, apabila fungsi itu dilaksanakan, objek aktif tempatan akan dimusnahkan, dan hanya skop global disimpan dalam ingatan, tetapi situasi dengan penutupan adalah berbeza.

Objek aktif penutupan masih akan disimpan dalam ingatan, jadi dalam contoh di atas, selepas panggilan fungsi kembali, pembolehubah i tergolong dalam objek aktif, yang bermaksud kawasan tindanannya belum dikeluarkan, tetapi anda memanggil c() Apabila rantaian skop yang disimpan oleh pembolehubah i pergi dari b()->a()-> ; hasil dalam penutupan, dan akhirnya Nilai output ialah 2;

Di atas ialah penutupan ungkapan fungsi dalam Asas JavaScript Bahagian 6 yang dikongsi oleh editor dengan anda.

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan