İki sentim ... Anlama şeklim bu. (Yanlışsam beni düzeltmekten çekinmeyin)
Değere / referansa göre geçiş hakkında bildiğiniz her şeyi atma zamanı.
Çünkü JavaScript'te, değere göre mi, referansla mı, yoksa neyle mi aktarıldığı önemli değil. Önemli olan mutasyona karşı bir fonksiyona aktarılan parametrelerin atanmasıdır.
Tamam, ne demek istediğimi açıklamak için elimden geleni yapayım. Diyelim ki birkaç nesneniz var.
var object1 = {};
var object2 = {};
Yaptığımız şey "atama" ... "object1" ve "object2" değişkenlerine 2 ayrı boş nesne atadık.
Şimdi diyelim ki object1'i daha çok seviyoruz ... Yani, yeni bir değişken "atarız".
var favoriteObject = object1;
Daha sonra, her ne sebeple olursa olsun, nesne 2'yi daha iyi sevmeye karar veriyoruz. Yani, sadece küçük bir yeniden görevlendirme yapıyoruz.
favoriteObject = object2;
Object1 veya object2'ye hiçbir şey olmadı. Hiçbir veriyi değiştirmedik. Tek yaptığımız, en sevdiğimiz nesnenin ne olduğunu yeniden atamaktı. Object2 ve favouriteObject öğelerinin her ikisinin de aynı nesneye atandığını bilmek önemlidir. Bu nesneyi bu değişkenlerden herhangi biriyle değiştirebiliriz.
object2.name = 'Fred';
console.log(favoriteObject.name) // Logs Fred
favoriteObject.name = 'Joe';
console.log(object2.name); // Logs Joe
Tamam, şimdi dizeler gibi ilkellere bakalım mesela
var string1 = 'Hello world';
var string2 = 'Goodbye world';
Yine, bir favori seçiyoruz.
var favoriteString = string1;
FavouriteString ve string1 değişkenlerimiz 'Hello world' a atanmıştır. Şimdi, ya favori favorimizi değiştirmek istiyorsak ??? Ne olacak???
favoriteString = 'Hello everyone';
console.log(favoriteString); // Logs 'Hello everyone'
console.log(string1); // Logs 'Hello world'
Ah oh .... Ne oldu. FavoriteString'i değiştirerek string1'i değiştiremedik ... Neden ?? Çünkü dize neslimizi değiştirmedik . Tüm yaptığımız yeni bir dizeye favoriteString değişkeni "RE ASSIGN" idi . Bu temelde string1 ile bağlantısını kesti. Önceki örnekte, nesnemizi yeniden adlandırdığımızda hiçbir şey atamadık. (Şey, değişkenin kendisine değil , ... ancak, name özelliğini yeni bir dizeye atadık.) Bunun yerine, sadece 2 değişken ile temeldeki nesneler arasındaki bağlantıları tutan nesneyi değiştirdik. (Biz değiştirmek veya istemişti bile mutasyona dize nesne kendisi, sahip olamadık, çünkü dizeler aslında JavaScript'te değiştirilemez.)
Şimdi, işlevlere ve parametreleri iletmeye devam ... Bir işlevi çağırdığınızda ve bir parametre ilettiğinizde, aslında yaptığınız şey yeni bir değişkene bir "atama" dır ve sadece kullanarak atadığınız gibi çalışır eşittir (=) işareti.
Bu örnekleri ele alalım.
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'
Şimdi, aynı şey, ama bir fonksiyonu ile
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'
Tamam, şimdi bunun yerine nesneleri kullanarak birkaç örnek verelim ... önce işlev olmadan.
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';
Şimdi, aynı şey, ama bir işlev çağrısı ile
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
Tamam, bu yazının tamamını okuduysanız, belki de artık işlev çağrılarının JavaScript'te nasıl çalıştığını daha iyi anlayabilirsiniz. Bir şeyin referansla mı yoksa değerle mi geçtiği önemli değil ... Önemli olan ödevle mutasyon arasında.
Bir değişkeni bir işleve her ilettiğinizde, tıpkı eşittir (=) işaretini kullandıysanız, parametre değişkeninin adı ne olursa olsun "Atarsınız".
Her zaman eşittir işaretinin (=) atama anlamına geldiğini unutmayın. JavaScript'te bir işleve parametre aktarmanın atama anlamına da geldiğini unutmayın. Bunlar aynıdır ve 2 değişken aynı şekilde bağlanmıştır (aynı nesneye atandıklarını saymadıkça, öyle değildirler).
"Bir değişkeni değiştirmenin" farklı bir değişkeni etkilediği tek zaman, temeldeki nesnenin mutasyona uğramasıdır (bu durumda değişkeni değiştirmediniz, ancak nesnenin kendisidir).
Nesneler ve ilkel öğeler arasında bir ayrım yapmanın bir anlamı yoktur, çünkü bir fonksiyonunuz yokmuş gibi çalışır ve sadece yeni bir değişkene atamak için eşittir işaretini kullanır.
Tek gotcha, işleve ilettiğiniz değişkenin adı, işlev parametresinin adıyla aynı olduğundadır. Bu olduğunda, işlevin içindeki parametreye, işleve özel tamamen yeni bir değişkenmiş gibi davranmanız gerekir (çünkü)
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'