JavaScript'te değişkenleri referans olarak nasıl geçiririm? Birkaç işlem yapmak istediğim 3 değişkenim var, bu yüzden onları bir for döngüsüne koymak ve her birine işlem yapmak istiyorum.
sözde kod:
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
Bunu yapmanın en iyi yolu nedir?
JavaScript'te "pass by reference" yoktur. Bir nesne aktarabilir (yani, bir nesneye referansı değer olarak aktarabilirsiniz) ve ardından bir fonksiyonun nesne içeriğini değiştirmesini sağlayabilirsiniz:
function alterObject(obj) {
obj.foo = "goodbye";
}
var myObj = { foo: "hello world" };
alterObject(myObj);
alert(myObj.foo); // "goodbye" instead of "hello world"
Bir dizinin özellikleri üzerinde sayısal bir dizinle yineleme yapabilir ve isterseniz dizinin her bir hücresini değiştirebilirsiniz.
var arr = [1, 2, 3];
for (var i = 0; i < arr.length; i++) {
arr[i] = arr[i] + 1;
}
Şunu belirtmek önemlidir ki "pass-by-reference" çok özel bir terimdir. Bu sadece değiştirilebilir bir nesneye referans aktarmanın mümkün olduğu anlamına gelmez. Bunun yerine, basit bir değişkeni, bir fonksiyonun çağıran bağlamda bu değeri değiştirmesine izin verecek şekilde geçirmenin mümkün olduğu anlamına gelir. Yani:
function swap(a, b) {
var tmp = a;
a = b;
b = tmp; //assign tmp to b
}
var x = 1, y = 2;
swap(x, y);
alert("x is " + x + ", y is " + y); // "x is 1, y is 2"
C++ gibi bir dilde bunu yapmak mümkündür çünkü bu dilde (bir nevi) pass-by-reference vardır.
edit — Bu konu yakın zamanda (Mart 2015) Reddit'te aşağıda bahsettiğim blog yazısına benzer bir yazı yüzünden tekrar patladı, ancak bu sefer Java ile ilgili. Reddit yorumlarındaki ileri geri konuşmaları okurken, kafa karışıklığının büyük bir kısmının "reference" kelimesini içeren talihsiz çarpışmadan kaynaklandığını fark ettim. Referansa göre geçiş" ve değere göre geçiş" terminolojisi, programlama dillerinde çalışmak için "nesnelere" sahip olma kavramından önce gelir. Bu aslında nesnelerle ilgili değildir; fonksiyon parametreleri ve özellikle fonksiyon parametrelerinin çağıran ortama nasıl "bağlandığı" (ya da bağlanmadığı) ile ilgilidir. Özellikle, gerçek bir pass-by-reference dilinde — nesneleri içeren — birinin hala nesne içeriklerini değiştirme yeteneğine sahip olacağını ve bunun JavaScript'te olduğu gibi görüneceğini unutmayın. Ancak, çağıran ortamdaki nesne referansını ayrıca değiştirmek mümkün olacaktır ve JavaScript'te yapamayacağınız en önemli şey budur. Bir pass-by-reference dili referansın kendisini değil, referansa bir referans iletecektir.
edit — burada konuyla ilgili bir blog yazısı var. (C++'ın gerçekte pass-by-reference olmadığını açıklayan bu yazıya yapılan yoruma dikkat edin. Bu doğru. Bununla birlikte, C++'ın sahip olduğu şey, bir işaretçi oluşturmak için işlev çağrısı noktasında açık bir şekilde veya argüman türü imzası bunun yapılmasını gerektiren işlevleri çağırırken örtük olarak düz değişkenlere referanslar oluşturma yeteneğidir. Bunlar JavaScript'in desteklemediği temel şeylerdir).
Değişkeni referans gibi geçirmek için geçici çözüm:
var a = 1;
inc = function(variableName) {
window[variableName] += 1;
};
inc('a');
alert(a); // 2
EDIT
Evet, aslında küresel erişim olmadan da yapabilirsiniz
inc = (function () {
var variableName = 0;
var init = function () {
variableName += 1;
alert(variableName);
}
return init;
})();
inc();
var ref = { value: 1 };
function Foo(x) {
x.value++;
}
Foo(ref);
Foo(ref);
alert(ref.value); // Alert: 3
rvar
function rvar (name, value, context) {
if (this instanceof rvar) {
this.value = value;
Object.defineProperty(this, 'name', { value: name });
Object.defineProperty(this, 'hasValue', { get: function () { return this.value !== undefined; } });
if ((value !== undefined) && (value !== null))
this.constructor = value.constructor;
this.toString = function () { return this.value + ''; };
} else {
if (!rvar.refs)
rvar.refs = {};
if (!context)
context = window;
// Private
rvar.refs[name] = new rvar(name, value);
// Public
Object.defineProperty(context, name, {
get: function () { return rvar.refs[name]; },
set: function (v) { rvar.refs[name].value = v; },
configurable: true
});
return context[name];
}
}
rvar('test_ref');
test_ref = 5; // test_ref.value = 5
Ya da:
rvar('test_ref', 5); // test_ref.value = 5
rvar('test_ref_number');
test_ref_number = 5;
function Fn1 (v) { v.value = 100; }
console.log("rvar('test_ref_number');");
console.log("test_ref_number = 5;");
console.log("function Fn1 (v) { v.value = 100; }");
console.log('test_ref_number.value === 5', test_ref_number.value === 5);
console.log(" ");
Fn1(test_ref_number);
console.log("Fn1(test_ref_number);");
console.log('test_ref_number.value === 100', test_ref_number.value === 100);
console.log(" ");
test_ref_number++;
console.log("test_ref_number++;");
console.log('test_ref_number.value === 101', test_ref_number.value === 101);
console.log(" ");
test_ref_number = test_ref_number - 10;
console.log("test_ref_number = test_ref_number - 10;");
console.log('test_ref_number.value === 91', test_ref_number.value === 91);
console.log(" ");
console.log("---------");
console.log(" ");
rvar('test_ref_str', 'a');
console.log("rvar('test_ref_str', 'a');");
console.log('test_ref_str.value === "a"', test_ref_str.value === 'a');
console.log(" ");
test_ref_str += 'bc';
console.log("test_ref_str += 'bc';");
console.log('test_ref_str.value === "abc"', test_ref_str.value === 'abc');
rvar('test_ref_number');
test_ref_number = 5;
function Fn1 (v) { v.value = 100; }
test_ref_number.value === 5 true
Fn1(test_ref_number);
test_ref_number.value === 100 true
test_ref_number++;
test_ref_number.value === 101 true
test_ref_number = test_ref_number - 10;
test_ref_number.value === 91 true
---------
rvar('test_ref_str', 'a');
test_ref_str.value === "a" true
test_ref_str += 'bc';
test_ref_str.value === "abc" true