Como passo variáveis por referência em JavaScript? Eu tenho 3 variáveis nas quais quero executar várias operações, então quero colocá-las em um loop for e executar as operações para cada uma.
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 fazer isso?
javascript
variables
pass-by-reference
BFTrick
fonte
fonte
makePretty(var1); makePretty(var2); makePretty(var3); ...
arr = [var1, var2, var3]; for (var i = 0, len = arr.length; i < len; i++) { arr[i] = makePretty(arr[i]); }
- você só precisa armazenar o valor retornado demakePretty
volta no slot na matriz.Respostas:
Não há "passagem por referência" disponível em JavaScript. Você pode transmitir um objeto (ou seja, pode passar por valor uma referência a um objeto) e, em seguida, fazer com que uma função modifique o conteúdo do objeto:
Você pode percorrer as propriedades de uma matriz com um índice numérico e modificar cada célula da matriz, se desejar.
É importante observar que "passagem por referência" é um termo muito específico. Isso não significa simplesmente que é possível passar uma referência a um objeto modificável. Em vez disso, significa que é possível passar uma variável simples de forma a permitir que uma função modifique esse valor no contexto de chamada . Assim:
Em uma linguagem como C ++, é possível fazer isso porque essa linguagem tem (mais ou menos) passagem por referência.
edit - isto recentemente (março de 2015) explodiu no Reddit novamente em uma postagem de blog semelhante à minha mencionada abaixo, embora neste caso sobre Java. Ocorreu-me enquanto lia as idas e vindas nos comentários do Reddit que grande parte da confusão decorre da infeliz colisão envolvendo a palavra "referência". A terminologia "passar por referência" e "passar por valor" antecede o conceito de ter "objetos" para trabalhar nas linguagens de programação. Realmente não se trata de objetos; trata-se de parâmetros de função e, especificamente, como os parâmetros de função estão "conectados" (ou não) ao ambiente de chamada. Em particular,, e seria muito parecido com o JavaScript. No entanto, também seria possível modificar a referência do objeto no ambiente de chamada, e é isso que você não pode fazer em JavaScript. Uma linguagem de passagem por referência passaria não a referência em si, mas uma referência à referência .
editar - aqui está uma postagem de blog sobre o tópico. (Observe o comentário dessa postagem que explica que o C ++ realmente não tem passagem por referência. Isso é verdade. O C ++ tem, no entanto, é a capacidade de criar referências a variáveis simples, explicitamente no ponto da função invocação para criar um ponteiro ou implicitamente ao chamar funções cuja assinatura de tipo de argumento exige que isso seja feito. Essas são as principais coisas que o JavaScript não suporta.)
fonte
Matrizes e objetos são passados por referência ou por valor com base nas seguintes condições:
se você estiver configurando o valor de um objeto ou matriz, é Passagem por valor.
object1 = {prop: "car"}; array1 = [1,2,3];
se você estiver alterando um valor de propriedade de um objeto ou matriz, será Passagem por referência.
object1.prop = "car"; array1[0] = 9;
Código
fonte
Solução alternativa para passar variáveis como por referência:
EDITAR
Sim, na verdade você pode fazê-lo sem acesso global
fonte
Objeto simples
Objeto personalizado
Objeto
rvar
Declaração Variável
Ou:
Código de teste
Resultado do console de teste
fonte
Ainda outra abordagem para passar quaisquer variáveis (locais, primitivas) por referência é envolver a variável com fechamento "on the fly" por
eval
. Isso também funciona com "use strict". (Nota: esteja ciente de queeval
não é amigável para otimizadores de JS, também a falta de aspas em torno do nome da variável pode causar resultados imprevisíveis)Amostra ao vivo https://jsfiddle.net/t3k4403w/
fonte
Na verdade, há uma solução bastante:
fonte
Eu tenho brincado com a sintaxe para fazer esse tipo de coisa, mas requer alguns ajudantes que são um pouco incomuns. Começa com o não uso de 'var', mas com um simples auxiliar 'DECLARE' que cria uma variável local e define um escopo para ela por meio de um retorno de chamada anônimo. Controlando como as variáveis são declaradas, podemos optar por envolvê-las em objetos para que elas sempre possam ser transmitidas por referência, essencialmente. Isso é semelhante a uma das respostas de Eduardo Cuomo acima, mas a solução abaixo não requer o uso de strings como identificadores de variáveis. Aqui está um código mínimo para mostrar o conceito.
fonte
na verdade é muito fácil,
o problema é entender que, depois de passar argumentos clássicos, você está no escopo de outra zona somente leitura.
soluções é passar os argumentos usando o design orientado a objetos do JavaScript,
é o mesmo que colocar os argumentos em uma variável global / com escopo, mas melhor ...
você também pode prometer coisas para aproveitar a cadeia conhecida: aqui está a coisa toda, com estrutura semelhante a promessas
ou melhor ainda ..
action.setArg(["empty-array"],"some string",0x100,"last argument").call()
fonte
this.arg
só funciona comaction
instância. Isso não funciona.Pessoalmente, não gosto da funcionalidade "passar por referência" oferecida por várias linguagens de programação. Talvez seja porque estou apenas descobrindo os conceitos de programação funcional, mas sempre fico arrepiado quando vejo funções que causam efeitos colaterais (como manipular parâmetros passados por referência). Pessoalmente, abraço fortemente o princípio da "responsabilidade única".
IMHO, uma função deve retornar apenas um resultado / valor usando a palavra-chave return. Em vez de modificar um parâmetro / argumento, eu retornaria o valor do parâmetro / argumento modificado e deixaria as reatribuições desejadas para o código de chamada.
Mas, às vezes (espero que muito raramente), é necessário retornar dois ou mais valores de resultado da mesma função. Nesse caso, eu optaria por incluir todos esses valores resultantes em uma única estrutura ou objeto. Novamente, o processamento de quaisquer reatribuições deve estar de acordo com o código de chamada.
Exemplo:
Suponha que a passagem de parâmetros seja suportada usando uma palavra-chave especial como 'ref' na lista de argumentos. Meu código pode ser algo como isto:
Em vez disso, eu preferiria fazer algo assim:
Quando eu precisaria escrever uma função que retorne vários valores, também não usaria parâmetros passados por referência. Então, eu evitaria códigos como este:
Em vez disso, eu preferiria retornar os dois novos valores dentro de um objeto, assim:
Esses exemplos de código são bastante simplificados, mas demonstram aproximadamente como eu pessoalmente lidaria com essas coisas. Isso me ajuda a manter várias responsabilidades no lugar correto.
Feliz codificação. :)
fonte
findStuff
simplesmente retornar a matriz resultante. Você também tem que declarar umafoundArray
variável, por isso gostaria de atribuir diretamente a matriz resultante para ele:var foundArray = findStuff(inArray); if (foundArray.length > 0) { /* process foundArray */ }
. Isso 1) tornaria o código de chamada mais legível / compreensível e 2) simplificaria consideravelmente a funcionalidade interna (e, portanto, também a testabilidade) dofindStuff
método, tornando-o muito mais flexível em diferentes (re) casos de uso / cenários.Javascript pode modificar itens de matriz dentro de uma função (é passado como uma referência ao objeto / matriz).
Aqui está outro exemplo:
fonte
Como o JS não é do tipo forte, ele permite que você resolva problemas de muitas maneiras diferentes, como parece neste passo.
No entanto, para o ponto de vista da sustentabilidade, eu teria que concordar com Bart Hofland. A função deve obter args para fazer algo e retornar o resultado. Tornando-os facilmente reutilizáveis.
Se você achar que as variáveis precisam ser passadas por referência, poderá ser melhor atendido Criando-as em objetos IMHO.
fonte
Deixando de lado a discussão de passagem por referência, aqueles que ainda procuram uma solução para a pergunta declarada podem usar:
fonte
Sei exatamente o que você quer dizer. A mesma coisa em Swift não será problema. Bottom line é usar
let
nãovar
.O fato de as primitivas serem passadas por valor, mas o fato de que o valor
var i
no ponto da iteração não é copiado para a função anônima é bastante surpreendente, para dizer o mínimo.fonte