Como posso passar variáveis por referência em JavaScript? Tenho 3 variáveis para as quais quero realizar várias operações, por isso quero colocá-las em loop e realizar as operações para cada uma delas.
pseudo- código:
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
Qual é a melhor maneira de o fazer?
Não há " passe por referência" disponível em JavaScript. Pode-se passar um objecto (ou seja, pode-se passar por valor de referência a um objecto) e depois ter uma função modificar o conteúdo do objecto:
function alterObject(obj) {
obj.foo = "goodbye";
}
var myObj = { foo: "hello world" };
alterObject(myObj);
alert(myObj.foo); // "goodbye" instead of "hello world"
Pode iterar sobre as propriedades de um array com um índice numérico e modificar cada célula do array, se quiser.
var arr = [1, 2, 3];
for (var i = 0; i < arr.length; i++) {
arr[i] = arr[i] + 1;
}
It's importante notar que "pass-by-reference" é um termo muito específico. Não significa simplesmente que é's possível passar uma referência a um objecto modificável. Em vez disso, significa que é's possível passar uma variável simples de modo a permitir que uma função modifique esse valor no contexto **calling***. Por isso:
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"
Numa língua como C++, é's possível fazer isso porque essa língua **does*** (sort-of) tem uma referência de passagem.
edit — este recentemente (Março de 2015) explodiu novamente na Reddit por causa de um post no blogue semelhante ao meu mencionado abaixo, embora neste caso sobre Java. Ocorreu-me enquanto lia o verso e a frente nos comentários do Reddit que uma grande parte da confusão deriva da infeliz colisão envolvendo a palavra "reference". A terminologia "passar por referência" e "passar por valor" é anterior ao conceito de ter "objectos" para trabalhar em linguagens de programação. It's realmente não tem nada a ver com objectos; it's sobre parâmetros de funções, e especificamente como são "connect" (ou não) ao ambiente de chamada. Em particular, note que numa verdadeira linguagem de passagem por referência — uma linguagem que contenta envolve objectos — ainda se teria a capacidade de modificar objectos contentes, e pareceria exactamente como se faz em JavaScript. Contudo, poder-se-ia também modificar a referência do objecto no ambiente de chamada, e isso'é a coisa chave que se can't faz em JavaScript. Uma linguagem de passagem por referência passaria não a referência em si, mas uma referência à referência.
edit — aqui está um post no blogue sobre o tópico (Note o comentário a esse post que explica que C++ não'não tem realmente uma referência de passagem por passagem. Isso é verdade. O que C+++ tem, contudo, é a capacidade de criar referências a variáveis simples, quer explicitamente no ponto de invocação da função para criar um ponteiro, ou implicitamente ao chamar funções cuja assinatura de tipo de argumento exige que isso seja feito. Estas são as coisas chave que o JavaScript não't suporta).
Solução para passar variável como por referência:
var a = 1;
inc = function(variableName) {
window[variableName] += 1;
};
inc('a');
alert(a); // 2
**EDIT***
yup, na verdade pode fazê-lo sem acesso global
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
Ou:
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