Bagaimana cara saya lulus variabel dengan referensi dalam JavaScript? Saya memiliki 3 variabel yang ingin saya lakukan beberapa operasi, jadi saya ingin meletakkannya dalam for loop dan melakukan operasi untuk masing-masing.
kode semu:
myArray = new Array(var1, var2, var3);
for (var x = 0; x < myArray.length; x++){
//do stuff to the array
makePretty(myArray[x]);
}
//now do stuff to the updated vars
Apa cara terbaik untuk melakukan ini?
javascript
variables
pass-by-reference
BFTrick
sumber
sumber
makePretty(var1); makePretty(var2); makePretty(var3); ...
arr = [var1, var2, var3]; for (var i = 0, len = arr.length; i < len; i++) { arr[i] = makePretty(arr[i]); }
- Anda hanya perlu menyimpan nilai yang dikembalikan denganmakePretty
kembali ke slot dalam array.Jawaban:
Tidak ada "pass by reference" yang tersedia di JavaScript. Anda dapat melewatkan sebuah objek (artinya, Anda dapat memberikan referensi kepada objek) dengan pass-by-value dan kemudian memiliki fungsi memodifikasi konten objek:
Anda bisa mengulangi properti array dengan indeks numerik dan memodifikasi setiap sel array, jika Anda mau.
Penting untuk dicatat bahwa "pass-by-reference" adalah istilah yang sangat spesifik. Ini tidak berarti hanya bahwa dimungkinkan untuk meneruskan referensi ke objek yang dapat dimodifikasi. Sebaliknya, itu berarti bahwa dimungkinkan untuk melewatkan variabel sederhana sedemikian rupa sehingga memungkinkan fungsi untuk mengubah nilai itu dalam konteks panggilan . Begitu:
Dalam bahasa seperti C ++, dimungkinkan untuk melakukan itu karena bahasa itu (sort-of) memiliki pass-by-reference.
sunting - ini baru-baru ini (Maret 2015) meledak di Reddit lagi atas posting blog yang mirip dengan saya yang disebutkan di bawah, meskipun dalam kasus ini tentang Java. Terpikir oleh saya ketika membaca bolak-balik dalam komentar Reddit bahwa sebagian besar kebingungan berasal dari tabrakan malang yang melibatkan kata "referensi". Terminologi "lulus dengan referensi" dan "lulus dengan nilai" mendahului konsep memiliki "objek" untuk bekerja dengan dalam bahasa pemrograman. Ini benar-benar bukan tentang benda sama sekali; ini tentang parameter fungsi, dan secara khusus bagaimana parameter fungsi "terhubung" (atau tidak) ke lingkungan panggilan. Secara khusus, perhatikan bahwa dalam bahasa referensi-by-referensi yang benar - bahasa yang benar, dan itu akan terlihat persis seperti di JavaScript. Namun, orang jugadapat memodifikasi referensi objek di lingkungan panggilan, dan itulah hal utama yang tidak dapat Anda lakukan dalam JavaScript. Bahasa pass-by-reference tidak akan melewati referensi itu sendiri, tetapi referensi ke referensi .
sunting - di sini ada posting blog tentang topik tersebut. (Catat komentar pada posting itu yang menjelaskan bahwa C ++ tidak benar-benar memiliki pass-by-reference. Itu benar. Apa yang dimiliki C ++, adalah kemampuan untuk membuat referensi ke variabel polos, baik secara eksplisit pada titik fungsi doa untuk membuat pointer, atau secara implisit saat memanggil fungsi yang jenis argumennya meminta hal itu dilakukan. Itulah hal-hal kunci yang tidak didukung JavaScript.)
sumber
Array dan Objek diteruskan dengan referensi atau berdasarkan nilai berdasarkan kondisi ini:
jika Anda menetapkan nilai suatu objek atau array, nilai Pass by Value.
object1 = {prop: "car"}; array1 = [1,2,3];
jika Anda mengubah nilai properti dari suatu objek atau array maka Pass by Reference.
object1.prop = "car"; array1[0] = 9;
Kode
sumber
Solusi untuk lulus variabel seperti dengan referensi:
EDIT
yup, sebenarnya Anda bisa melakukannya tanpa akses global
sumber
Obyek Sederhana
Objek Khusus
Obyek
rvar
Deklarasi Variabel
Atau:
Kode Uji
Hasil Konsol Tes
sumber
Namun pendekatan lain untuk melewatkan variabel (lokal, primitif) dengan referensi adalah dengan membungkus variabel dengan penutupan "on the fly" oleh
eval
. Ini juga berfungsi dengan "gunakan ketat". (Catatan: perlu diketahui bahwaeval
tidak ramah untuk pengoptimal JS, juga kutipan yang hilang di sekitar nama variabel dapat menyebabkan hasil yang tidak terduga)Sampel langsung https://jsfiddle.net/t3k4403w/
sumber
Sebenarnya ada solusi yang cukup:
sumber
Saya telah bermain-main dengan sintaks untuk melakukan hal semacam ini, tetapi membutuhkan beberapa pembantu yang sedikit tidak biasa. Itu dimulai dengan tidak menggunakan 'var' sama sekali, tetapi pembantu 'DECLARE' sederhana yang membuat variabel lokal dan mendefinisikan ruang lingkup untuk itu melalui panggilan balik anonim. Dengan mengendalikan bagaimana variabel dideklarasikan, kita dapat memilih untuk membungkusnya menjadi objek sehingga mereka selalu dapat dilewatkan dengan referensi, pada dasarnya. Ini mirip dengan salah satu jawaban Eduardo Cuomo di atas, tetapi solusi di bawah ini tidak memerlukan penggunaan string sebagai pengidentifikasi variabel. Berikut adalah beberapa kode minimal untuk menunjukkan konsep.
sumber
sebenarnya sangat mudah,
masalahnya adalah memahami bahwa setelah melewati argumen klasik, Anda dimasukkan ke argumen lain, zona read-only.
solusi adalah untuk melewati argumen menggunakan desain berorientasi objek JavaScript,
itu sama dengan menempatkan args dalam variabel global / cakupan, tetapi lebih baik ...
Anda juga dapat menjanjikan hal-hal untuk menikmati rantai terkenal: di sini semuanya, dengan struktur seperti janji
atau lebih baik lagi ..
action.setArg(["empty-array"],"some string",0x100,"last argument").call()
sumber
this.arg
hanya bekerja denganaction
instance. Ini tidak bekerja.Saya pribadi tidak menyukai fungsi "pass by reference" yang ditawarkan oleh berbagai bahasa pemrograman. Mungkin itu karena saya hanya menemukan konsep pemrograman fungsional, tetapi saya selalu merinding ketika saya melihat fungsi yang menyebabkan efek samping (seperti memanipulasi parameter yang dilewatkan oleh referensi). Saya pribadi sangat menganut prinsip "tanggung jawab tunggal".
IMHO, suatu fungsi harus mengembalikan hanya satu hasil / nilai menggunakan kata kunci kembali. Alih-alih memodifikasi parameter / argumen, saya hanya akan mengembalikan nilai parameter / argumen yang dimodifikasi dan membiarkan penugasan kembali yang diinginkan ke kode panggilan.
Tapi kadang-kadang (mudah-mudahan sangat jarang), perlu mengembalikan dua atau lebih nilai hasil dari fungsi yang sama. Dalam hal ini, saya akan memilih untuk memasukkan semua nilai yang dihasilkan dalam struktur atau objek tunggal. Sekali lagi, memproses setiap penugasan kembali harus sesuai dengan kode panggilan.
Contoh:
Misalkan parameter lewat akan didukung dengan menggunakan kata kunci khusus seperti 'ref' dalam daftar argumen. Kode saya mungkin terlihat seperti ini:
Sebaliknya, saya sebenarnya lebih suka melakukan sesuatu seperti ini:
Ketika saya perlu menulis fungsi yang mengembalikan beberapa nilai, saya juga tidak akan menggunakan parameter yang dilewati oleh referensi. Jadi saya akan menghindari kode seperti ini:
Sebaliknya, saya sebenarnya lebih suka mengembalikan kedua nilai baru di dalam objek, seperti ini:
Contoh kode ini cukup disederhanakan, tetapi secara kasar menunjukkan bagaimana saya secara pribadi akan menangani hal-hal seperti itu. Ini membantu saya untuk menjaga berbagai tanggung jawab di tempat yang benar.
Selamat coding. :)
sumber
findStuff
mengembalikan array yang dihasilkan. Anda juga harus mendeklarasikanfoundArray
variabel, jadi saya akan langsung menetapkan array yang dihasilkan untuk itu:var foundArray = findStuff(inArray); if (foundArray.length > 0) { /* process foundArray */ }
. Ini akan 1) membuat kode panggilan lebih mudah dibaca / dimengerti, dan 2) menyederhanakan fungsi internal (dan juga testabilitas) darifindStuff
metode tersebut, menjadikannya jauh lebih fleksibel dalam berbagai skenario penggunaan kembali kasus / skenario.Javascript dapat mengubah item array di dalam suatu fungsi (diteruskan sebagai referensi ke objek / array).
Ini contoh lain:
sumber
JS bukan tipe yang kuat, ini memungkinkan Anda untuk menyelesaikan masalah dengan berbagai cara, seperti yang terlihat dalam tapak ini.
Namun, untuk sudut pandang rawatan, saya harus setuju dengan Bart Hofland. Fungsi harus mendapatkan argumen untuk melakukan sesuatu dan mengembalikan hasilnya. Membuatnya mudah digunakan kembali.
Jika Anda merasa bahwa variabel perlu diteruskan dengan referensi, Anda mungkin lebih baik dilayani. Membangunnya menjadi objek IMHO.
sumber
Mengesampingkan diskusi pass-by-reference, mereka yang masih mencari solusi untuk pertanyaan yang disebutkan dapat menggunakan:
sumber
Saya tahu persis apa yang Anda maksud. Hal yang sama di Swift tidak akan menjadi masalah. Intinya adalah gunakan
let
tidakvar
.Fakta bahwa primitif disahkan oleh nilai tetapi fakta bahwa nilai
var i
pada titik iterasi tidak disalin ke fungsi anonim cukup mengejutkan untuk sedikitnya.sumber