如何在JavaScript中通过引用传递变量?我有3个变量,我想对它们进行一些操作,所以我想把它们放在一个for循环中,对每个变量进行操作。
伪装代码。
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
最好的方法是什么?
在JavaScript中没有"通过引用传递"。你可以传递一个对象(也就是说,你可以通过值传递一个对象的引用),然后让一个函数修改对象的内容。
function alterObject(obj) {
obj.foo = "goodbye";
}
var myObj = { foo: "hello world" };
alterObject(myObj);
alert(myObj.foo); // "goodbye" instead of "hello world"
你可以用数字索引遍历一个数组的属性,如果你想的话,可以修改数组的每个单元。
var arr = [1, 2, 3];
for (var i = 0; i < arr.length; i++) {
arr[i] = arr[i] + 1;
}
需要注意的是,"pass-by-reference" 是一个非常具体的术语。它并不意味着可以将一个引用传递给一个可修改的对象。相反,它意味着有可能以这样一种方式传递一个简单的变量,从而允许一个函数在调用的上下文中修改该值。 所以。
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++这样的语言中,有可能做到这一点,因为该语言确实(某种程度上)有逐个传递的功能。
edit —最近(2015年3月)在Reddit上又因为一篇与下面提到的我的博文而炸开了锅,不过这次是关于Java。我在阅读Reddit评论中的来来回回时想到,混乱的很大一部分源于涉及"reference"这个词的不幸碰撞。术语"通过引用传递"和"通过值传递"早于编程语言中拥有"对象"的概念。它实际上根本不是关于对象的;它是关于函数参数的,特别是关于函数参数如何与调用环境连接(或不连接)的。特别要注意的是,在真正的逐一引用语言中,一个确实涉及到对象的语言,人们仍然有能力修改对象的内容,而且看起来与JavaScript中的情况几乎完全一样。然而,人们也可以在调用环境中修改对象的引用,而这正是你在JavaScript中无法做到的关键所在。一个逐一传递的语言不是传递引用本身,而是传递对引用的*引用。
编辑 —这里有一篇关于这个话题的博文。 (注意那篇博文的评论,它解释说C++并没有真正的逐一引用。 这倒是真的。然而,C++确实有能力创建对普通变量的引用,要么在函数调用时明确地创建一个指针,要么在调用参数类型签名要求这样做的函数时隐含地*。这些都是JavaScript不支持的关键内容。)
解决方法是通过引用来传递变量。
var a = 1;
inc = function(variableName) {
window[variableName] += 1;
};
inc('a');
alert(a); // 2
编辑
是的,实际上你可以在没有访问权限的情况下做到这一点。
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
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
或者。
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