Dua sen saya ... Ini adalah cara saya memahaminya. (Jangan ragu untuk mengoreksi saya jika saya salah)
Saatnya membuang semua yang Anda ketahui tentang nilai / referensi.
Karena dalam JavaScript, tidak masalah apakah itu diteruskan oleh nilai atau referensi atau apa pun. Yang penting adalah mutasi vs penugasan parameter dilewatkan ke fungsi.
OK, biarkan saya melakukan yang terbaik untuk menjelaskan apa yang saya maksud. Katakanlah Anda memiliki beberapa objek.
var object1 = {};
var object2 = {};
Apa yang telah kami lakukan adalah "tugas" ... Kami telah menetapkan 2 objek kosong terpisah ke variabel "object1" dan "object2".
Sekarang, katakanlah kita menyukai objek1 lebih baik ... Jadi, kita "menetapkan" variabel baru.
var favoriteObject = object1;
Selanjutnya, untuk alasan apa pun, kami memutuskan bahwa kami lebih suka objek 2. Jadi, kami hanya melakukan sedikit penugasan ulang.
favoriteObject = object2;
Tidak ada yang terjadi pada object1 atau object2. Kami belum mengubah data apa pun. Yang kami lakukan hanyalah menetapkan ulang apa objek favorit kami. Penting untuk mengetahui bahwa object2 dan favoriteObject keduanya ditugaskan untuk objek yang sama. Kita dapat mengubah objek itu melalui salah satu variabel tersebut.
object2.name = 'Fred';
console.log(favoriteObject.name) // Logs Fred
favoriteObject.name = 'Joe';
console.log(object2.name); // Logs Joe
OK, sekarang mari kita lihat primitif seperti string misalnya
var string1 = 'Hello world';
var string2 = 'Goodbye world';
Sekali lagi, kami memilih favorit.
var favoriteString = string1;
Variabel favoriteString dan string1 kami ditugaskan ke 'Hello world'. Sekarang, bagaimana jika kita ingin mengubah Stringsing favorit kita ??? Apa yang akan terjadi???
favoriteString = 'Hello everyone';
console.log(favoriteString); // Logs 'Hello everyone'
console.log(string1); // Logs 'Hello world'
Uh oh .... Apa yang terjadi. Kami tidak dapat mengubah string1 dengan mengubahString favorit ... Mengapa ?? Karena kami tidak mengubah objek string kami . Yang kami lakukan adalah "RE ASSIGN" variabel favoriteString ke string baru. Ini pada dasarnya memutusnya dari string1. Pada contoh sebelumnya, ketika kami mengganti nama objek kami, kami tidak menetapkan apa pun. (Yah, bukan ke variabel itu sendiri , ... kami, bagaimanapun, menetapkan properti nama ke string baru.) Sebaliknya, kami hanya bermutasi objek yang menjaga koneksi antara 2 variabel dan objek yang mendasarinya. (Bahkan jika kita ingin memodifikasi atau mengubah objek string itu sendiri, kami tidak dapat melakukannya, karena string sebenarnya tidak dapat diubah dalam JavaScript.)
Sekarang, ke fungsi dan melewati parameter .... Ketika Anda memanggil fungsi, dan melewatkan parameter, apa yang Anda lakukan pada dasarnya adalah "tugas" ke variabel baru, dan berfungsi persis sama seperti jika Anda hanya ditugaskan menggunakan tanda sama dengan (=).
Ambil contoh ini.
var myString = 'hello';
// Assign to a new variable (just like when you pass to a function)
var param1 = myString;
param1 = 'world'; // Re assignment
console.log(myString); // Logs 'hello'
console.log(param1); // Logs 'world'
Sekarang, hal yang sama, tetapi dengan suatu fungsi
function myFunc(param1) {
param1 = 'world';
console.log(param1); // Logs 'world'
}
var myString = 'hello';
// Calls myFunc and assigns param1 to myString just like param1 = myString
myFunc(myString);
console.log(myString); // logs 'hello'
OK, sekarang mari kita berikan beberapa contoh menggunakan objek saja ... pertama, tanpa fungsi.
var myObject = {
firstName: 'Joe',
lastName: 'Smith'
};
// Assign to a new variable (just like when you pass to a function)
var otherObj = myObject;
// Let's mutate our object
otherObj.firstName = 'Sue'; // I guess Joe decided to be a girl
console.log(myObject.firstName); // Logs 'Sue'
console.log(otherObj.firstName); // Logs 'Sue'
// Now, let's reassign the variable
otherObj = {
firstName: 'Jack',
lastName: 'Frost'
};
// Now, otherObj and myObject are assigned to 2 very different objects
// And mutating one object has no influence on the other
console.log(myObject.firstName); // Logs 'Sue'
console.log(otherObj.firstName); // Logs 'Jack';
Sekarang, hal yang sama, tetapi dengan pemanggilan fungsi
function myFunc(otherObj) {
// Let's mutate our object
otherObj.firstName = 'Sue';
console.log(otherObj.firstName); // Logs 'Sue'
// Now let's re-assign
otherObj = {
firstName: 'Jack',
lastName: 'Frost'
};
console.log(otherObj.firstName); // Logs 'Jack'
// Again, otherObj and myObject are assigned to 2 very different objects
// And mutating one object doesn't magically mutate the other
}
var myObject = {
firstName: 'Joe',
lastName: 'Smith'
};
// Calls myFunc and assigns otherObj to myObject just like otherObj = myObject
myFunc(myObject);
console.log(myObject.firstName); // Logs 'Sue', just like before
OK, jika Anda membaca seluruh posting ini, mungkin Anda sekarang memiliki pemahaman yang lebih baik tentang cara kerja pemanggilan fungsi dalam JavaScript. Tidak masalah apakah sesuatu dilewatkan dengan referensi atau berdasarkan nilai ... Yang penting adalah penugasan vs mutasi.
Setiap kali Anda melewatkan variabel ke suatu fungsi, Anda "Menugaskan" ke apa pun nama variabel parameternya, sama seperti jika Anda menggunakan tanda sama dengan (=).
Selalu ingat bahwa tanda sama dengan (=) berarti tugas. Selalu ingat bahwa meneruskan parameter ke fungsi dalam JavaScript juga berarti tugas. Mereka sama dan 2 variabel terhubung dengan cara yang persis sama (artinya tidak, kecuali Anda menghitung bahwa mereka ditugaskan ke objek yang sama).
Satu-satunya waktu "memodifikasi variabel" mempengaruhi variabel yang berbeda adalah ketika objek yang mendasarinya dimutasi (dalam hal ini Anda belum mengubah variabel, tetapi objek itu sendiri.
Tidak ada gunanya membuat perbedaan antara objek dan primitif, karena ia bekerja dengan cara yang persis sama seolah-olah Anda tidak memiliki fungsi dan hanya menggunakan tanda sama dengan untuk menetapkan ke variabel baru.
Satu-satunya gotcha adalah ketika nama variabel yang Anda masukkan ke dalam fungsi sama dengan nama parameter fungsi. Ketika ini terjadi, Anda harus memperlakukan parameter di dalam fungsi seolah-olah itu adalah variabel baru pribadi untuk fungsi (karena itu)
function myFunc(myString) {
// myString is private and does not affect the outer variable
myString = 'hello';
}
var myString = 'test';
myString = myString; // Does nothing, myString is still 'test';
myFunc(myString);
console.log(myString); // Logs 'test'