Dalam JavaScript, dengan digunakan untuk memanjangkan rantaian skop pernyataan Ia biasanya digunakan sebagai pintasan untuk merujuk berulang kali berbilang sifat dalam objek yang sama tanpa berulang kali merujuk objek itu sendiri ialah "dengan (. ungkapan) {laksanakan pernyataan...}".
Persekitaran pengendalian tutorial ini: sistem Windows 7, versi JavaScript 1.8.5, komputer Dell G3.
Penggunaan asas javascript dengan
Niat asal pernyataan with adalah untuk menyediakan pintasan gaya ruang nama untuk peringkat demi peringkat akses objek. Juga Iaitu, dalam kawasan kod yang ditentukan, objek dipanggil terus melalui nama nod.
Pernyataan dengan digunakan untuk melanjutkan rantaian skop pernyataan. Sintaks adalah seperti berikut:
with (expression) { statement }
ungkapan
Menambah ungkapan yang diberikan pada rantai skop yang digunakan semasa menilai pernyataan. Tanda kurung di sekeliling ungkapan diperlukan.
kenyataan
Sebarang kenyataan. Untuk melaksanakan berbilang pernyataan, gunakan pernyataan blok ({ ... }) untuk mengumpulkan pernyataan.
dengan biasanya digunakan sebagai pintasan untuk merujuk berulang kali berbilang sifat dalam objek yang sama tanpa merujuk objek itu sendiri berulang kali.
Sebagai contoh, pada masa ini terdapat objek seperti ini:
var obj = { a: 1, b: 2, c: 3 };
Jika anda ingin menukar nilai setiap item dalam obj, kaedah penulisan umum mungkin seperti ini:
// 重复写了3次的“obj” obj.a = 2; obj.b = 3; obj.c = 4;
Jika anda menggunakan kaedah penulisan with, akan ada jalan pintas mudah
with (obj) { a = 3; b = 4; c = 5; }
Dalam kod ini, pernyataan with digunakan untuk mengaitkan objek obj, yang bermaksud bahawa di dalam dengan blok kod , setiap pembolehubah pertama kali dianggap sebagai pembolehubah tempatan Jika pembolehubah tempatan mempunyai nama yang sama dengan sifat objek obj, maka pembolehubah tempatan ini akan menunjuk ke sifat objek obj.
Kelemahan dengan
Dalam contoh di atas, kita dapat melihat bahawa with boleh membantu kita memudahkan kod dengan baik . Tetapi mengapa ia tidak disyorkan? Mari kita bincangkan tentang kelemahan dengan:
Membawa kepada kebocoran data
Mari kita lihat bahagian kod berikut
function foo(obj) { with (obj) { a = 2; } } var o1 = { a: 3 }; var o2 = { b: 3 } foo(o1); console.log(o1.a); //2 foo(o2); console.log(o2.a); //underfined console.log(a); //2,a被泄漏到全局作用域上
Pertama, kita Mari analisa kod di atas. Dalam contoh, dua objek o1 dan o2 dicipta. Satu daripada mereka mempunyai sifat, yang satu lagi tidak. foo(obj)
Fungsi menerima parameter rasmi obj, yang merupakan rujukan objek dan melaksanakan with(obj) {...}
pada rujukan objek. Di dalam blok dengan, terdapat rujukan leksikal kepada a, yang sebenarnya merupakan rujukan LHS, dan 2 diberikan kepadanya.
Apabila kita melepasi o1, a = 2
operasi penugasan mencari o1.a dan memberikan 2 kepadanya. Apabila o2 diluluskan, o2 tidak mempunyai sifat, jadi sifat ini tidak akan dicipta dan o2.a kekal tidak ditentukan.
Tetapi mengapa operasi o2 membawa kepada kebocoran data?
Di sini kita perlu kembali kepada mekanisme LHS查询
.
Apabila kita melepasi o2 kepada dengan, skop yang diisytiharkan oleh dengan ialah o2, dan LHS查询
bermula dari skop ini kepada a. Pengecam a tidak ditemui dalam skop o2, skop foo(…) dan skop global, jadi dalam mod tidak ketat, pembolehubah global akan dicipta secara automatik dalam skop global), dalam Dalam mod ketat, pengecualian ReferenceError
akan dilemparkan.
Sebab lain mengapa dengan tidak disyorkan. Dalam mod yang ketat, dengan adalah dilarang sama sekali, seperti penggunaan tidak langsung atau tidak selamat bagi eval(…).
Kemerosotan prestasi
dengan mengubah suai atau mencipta skop baharu pada masa jalan, dengan itu memperdaya skop leksikal lain yang ditakrifkan pada masa tulis. dengan boleh membuat kod lebih berskala Walaupun terdapat kemungkinan kebocoran data di atas, ia boleh dielakkan dengan sedikit perhatian.
Jawapannya adalah tidak. Mari lihat bahagian kod berikut untuk sebab tertentu.
Kod berikut boleh terus disalin dan dijalankan
<script> function func() { console.time("func"); var obj = { a: [1, 2, 3] }; for(var i = 0; i < 100000; i++) { var v = obj.a[0]; } console.timeEnd("func"); } func(); function funcWith() { console.time("funcWith"); var obj = { a: [1, 2, 3] }; with(obj) { for(var i = 0; i < 100000; i++) { var v = a[0]; } } console.timeEnd("funcWith"); } funcWith(); </script>
Kemudian, kesan ujian:
Dalam kod yang mengendalikan logik yang sama, masa berjalan tanpa menggunakan dengan hanya 4.63 ms. Masa penggunaan menggunakan dengan adalah selama 81.87ms.
Kenapa ni?
Sebabnya ialah enjin JavaScript akan melakukan beberapa pengoptimuman prestasi semasa fasa penyusunan. Sesetengah pengoptimuman ini bergantung pada keupayaan untuk menganalisis kod secara statik berdasarkan leksikonnya dan pratentukan tempat semua pembolehubah dan fungsi ditakrifkan supaya pengecam boleh ditemui dengan cepat semasa pelaksanaan.
Tetapi jika enjin menjumpai dengan dalam kod, ia hanya boleh menganggap bahawa sebarang pertimbangan tentang kedudukan pengecam adalah tidak sah, kerana tiada cara untuk mengetahui objek yang dihantar kepada untuk mencipta skop leksikal baharu Apa sebenarnya kandungannya.
Kes yang paling pesimis ialah jika dengan muncul, semua pengoptimuman mungkin tidak bermakna. Oleh itu, pendekatan paling mudah yang akan diambil oleh enjin ialah tidak melakukan sebarang pengoptimuman sama sekali. Jika kod menggunakan banyak dengan atau eval(), ia pasti akan berjalan dengan sangat perlahan. Tidak kira betapa pintarnya enjin dalam cuba meminimumkan kesan sampingan senario pesimis ini, ia tidak dapat mengelakkan hakikat bahawa tanpa pengoptimuman ini, kod akan berjalan lebih perlahan .
[Cadangan berkaitan: tutorial video javascript, bahagian hadapan web]
Atas ialah kandungan terperinci Bagaimana untuk menggunakan dengan dalam javascript. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!