Rumah  >  Artikel  >  hujung hadapan web  >  Analisis ringkas tentang fungsi tanpa nama Javascript dan kemahiran functions_javascript laksana sendiri

Analisis ringkas tentang fungsi tanpa nama Javascript dan kemahiran functions_javascript laksana sendiri

WBOY
WBOYasal
2016-05-16 15:16:001055semak imbas

Fungsi ialah objek paling fleksibel dalam JavaScript Di sini kami hanya menerangkan penggunaan fungsi tanpa namanya. Fungsi tanpa nama: Ia adalah fungsi tanpa nama fungsi.

Takrifan fungsi boleh dibahagikan secara kasar kepada tiga cara:

Jenis pertama: Ini juga merupakan jenis yang paling biasa

function double(x){ 
return 2 * x; 
}

Kaedah kedua: Kaedah ini menggunakan pembina Fungsi dan menganggap kedua-dua senarai parameter dan badan fungsi sebagai rentetan Ini sangat menyusahkan dan tidak disyorkan.

var double = new Function('x', 'return 2 * x;');

Jenis ketiga:

var double = function(x) { return 2* x; }

Perhatikan bahawa fungsi di sebelah kanan "=" ialah fungsi tanpa nama Selepas mencipta fungsi, fungsi itu diberikan kepada petak pembolehubah.

Penciptaan fungsi tanpa nama

Kaedah pertama ialah mentakrifkan fungsi segi empat sama seperti yang dinyatakan di atas, yang juga merupakan salah satu kaedah yang paling biasa digunakan.

Cara kedua:

(function(x, y){ 
alert(x + y); 
})(2, 3);

Fungsi tanpa nama dicipta di sini (di dalam kurungan pertama), dan kurungan kedua digunakan untuk memanggil fungsi tanpa nama dan menghantar parameter. Tanda kurung ialah ungkapan, dan ungkapan mempunyai nilai pulangan, jadi anda boleh menambah sepasang kurungan selepasnya untuk melaksanakannya

Melaksanakan sendiri fungsi tanpa nama

1. Apakah fungsi tanpa nama yang dilaksanakan sendiri?

Ia merujuk kepada fungsi yang kelihatan seperti ini: (function {// code})();

2. Soalan

Mengapa (fungsi {// kod})(); boleh dilaksanakan, tetapi fungsi {// kod}();

3. Analisis


(1). Pertama sekali, kita perlu memahami perbezaan antara keduanya:

(function {// code}) ialah ungkapan, function {// code} ialah pengisytiharan fungsi.
(2). Kedua, ciri-ciri js "precompilation":
Dalam fasa "pra-penyusun" js, pengisytiharan fungsi akan ditafsirkan, tetapi ungkapan akan diabaikan.
(3). Apabila js melaksanakan function() {//code}();, kerana function() {//code} telah ditafsirkan dalam peringkat "precompilation", js akan melangkau function(){/ /code}, cuba melaksanakan ();, jadi ralat akan dilaporkan; Apabila js melaksanakan (fungsi {// kod})();, kerana (fungsi {// kod}) ialah ungkapan, js akan menyelesaikannya untuk mendapatkan nilai pulangan Memandangkan nilai pulangan ialah fungsi, ia menemui () ;, ia akan dilaksanakan.

Selain itu, kaedah menukar fungsi kepada ungkapan tidak semestinya bergantung pada operator pengelompokan () Kita juga boleh menggunakan operator void, ~ operator, operator...

Contohnya:

!function(){ 
alert("另类的匿名函数自执行"); 
}();

Fungsi tanpa nama dan penutupan Perkataan bahasa Inggeris untuk penutupan ialah penutupan, yang merupakan bahagian pengetahuan yang sangat penting dalam JavaScript, kerana penggunaan penutupan boleh mengurangkan jumlah kod kami, menjadikan kod kami kelihatan lebih jelas, dsb. Pendek kata, ia sangat berkuasa.

Maksud penutupan: Secara terang-terangan, penutupan ialah sarang fungsi Fungsi dalam boleh menggunakan semua pembolehubah fungsi luar, walaupun fungsi luar telah dilaksanakan (ini melibatkan rantaian skop JavaScript).

function checkClosure(){ 
var str = 'rain-man'; 
setTimeout( 
function(){ alert(str); } //这是一个匿名函数 
, 2000); 
} 
checkClosure();

Contoh ini kelihatan sangat mudah masih terdapat banyak mata pengetahuan selepas analisis teliti proses pelaksanaannya: pelaksanaan fungsi checkClosure adalah serta-merta (mungkin hanya mengambil masa 0.00001 milisaat), dan str pembolehubah dibuat dalam badan fungsi daripada checkClosure , str tidak dikeluarkan selepas checkClosure dilaksanakan, kerana fungsi tanpa nama dalam setTimeout mempunyai rujukan kepada str. Selepas 2 saat, fungsi tanpa nama dalam badan fungsi dilaksanakan dan str dikeluarkan.

Gunakan penutupan untuk mengoptimumkan kod:

function forTimeout(x, y){ 
alert(x + y); 
} 
function delay(x , y , time){ 
setTimeout('forTimeout(' + x + ',' + y + ')' , time); 
} 
/** 
* 上面的delay函数十分难以阅读,也不容易编写,但如果使用闭包就可以让代码更加清晰 
* function delay(x , y , time){ 
* setTimeout( 
* function(){ 
* forTimeout(x , y) 
* } 
* , time); 
* } 
*/
Penggunaan terbesar fungsi tanpa nama adalah untuk membuat penutupan (yang merupakan salah satu ciri bahasa JavaScript), dan juga boleh membina ruang nama untuk mengurangkan penggunaan pembolehubah global.

var oEvent = {}; 
(function(){ 
var addEvent = function(){ /*代码的实现省略了*/ }; 
function removeEvent(){} 

oEvent.addEvent = addEvent; 
oEvent.removeEvent = removeEvent; 
})();
Dalam kod ini, fungsi addEvent dan removeEvent ialah pembolehubah tempatan, tetapi kita boleh menggunakannya melalui pembolehubah global oEvent, yang mengurangkan penggunaan pembolehubah global dan meningkatkan keselamatan halaman web dengan ketara.

Kami mahu menggunakan kod ini:

oEvent.addEvent(document.getElementById('box') , 'click' , function(){});
var rainman = (function(x , y){ 
return x + y; 
})(2 , 3); 
/** 
* 也可以写成下面的形式,因为第一个括号只是帮助我们阅读,但是不推荐使用下面这种书写格式。 
* var rainman = function(x , y){ 
* return x + y; 
* }(2 , 3);
Di sini kami mencipta rainman berubah-ubah dan memulakannya kepada 5 dengan memanggil terus fungsi tanpa nama ini kadangkala sangat praktikal.

var outer = null; 
(function(){ 
var one = 1; 
function inner (){ 
one += 1; 
alert(one); 
} 
outer = inner; 
})(); 
outer(); //2 
outer(); //3 
outer(); //4
Pembolehubah dalam kod ini ialah pembolehubah tempatan (kerana ia ditakrifkan dalam fungsi), jadi ia tidak boleh diakses dari luar. Tetapi di sini kami mencipta fungsi dalam, yang boleh mengakses pembolehubah satu; dan pembolehubah global luar merujuk kepada dalam, jadi memanggil luar tiga kali akan muncul hasil tambahan.

Perhatian 1 Penutupan membenarkan fungsi dalaman merujuk kepada pembolehubah dalam fungsi induk, tetapi pembolehubah ialah nilai akhir

你会发现当鼠标移过每一个25edfb22a4f469ecb59f1190150159c6元素时,总是弹出4,而不是我们期待的元素下标。这是为什么呢?注意事项里已经讲了(最终值)。显然这种解释过于简单,当mouseover事件调用监听函数时,首先在匿名函数( function(){ alert(i); })内部查找是否定义了 i,结果是没有定义;因此它会向上查找,查找结果是已经定义了,并且i的值是4(循环后的i值);所以,最终每次弹出的都是4。

解决方法一:

var lists = document.getElementsByTagName('li'); 
for(var i = 0 , len = lists.length ; i < len ; i++){ 
(function(index){ 
lists[ index ].onmouseover = function(){ 
alert(index); 
}; 
})(i); 
}

解决方法二:

var lists = document.getElementsByTagName('li'); 
for(var i = 0, len = lists.length; i < len; i++){ 
lists[ i ].$$index = i; //通过在Dom元素上绑定$$index属性记录下标 
lists[ i ].onmouseover = function(){ 
alert(this.$$index); 
}; 
}

解决方法三:

function eventListener(list, index){ 
list.onmouseover = function(){ 
alert(index); 
}; 
} 
var lists = document.getElementsByTagName('li'); 
for(var i = 0 , len = lists.length ; i < len ; i++){ 
eventListener(lists[ i ] , i); 
}

2 内存泄露

使用闭包十分容易造成浏览器的内存泄露,严重情况下会是浏览器挂死

Kenyataan:
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