-
Notifications
You must be signed in to change notification settings - Fork 111
Objects references and copying #223
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 10 commits
317a62c
079b171
095ac89
3aa40e5
23f071e
ddb06b5
d4b9a35
8721090
c6562a8
feb1938
2224acc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,116 +1,116 @@ | ||||||
| # Object references and copying | ||||||
| # Referências de objetos e cópias | ||||||
|
|
||||||
| One of the fundamental differences of objects versus primitives is that objects are stored and copied "by reference", whereas primitive values: strings, numbers, booleans, etc -- are always copied "as a whole value". | ||||||
| Uma das diferenças fundamentais de objetos em relação aos primitivos é que objetos são armazenados e copiados por "referência", enquanto valores primitivos: strings, números, booleanos, etc - são sempre copiados por "valor". | ||||||
|
|
||||||
| That's easy to understand if we look a bit under the hood of what happens when we copy a value. | ||||||
| Isso é fácil de entender quando olhamos um pouco nos bastidores do que acontece quando copiamos um valor. | ||||||
matdomis marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
|
||||||
| Let's start with a primitive, such as a string. | ||||||
| Vamos começar com um primitivo, como uma string. | ||||||
matdomis marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
|
||||||
| Here we put a copy of `message` into `phrase`: | ||||||
| Aqui colocamos uma copia de `message` para `phrase`: | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| ```js | ||||||
| let message = "Hello!"; | ||||||
| let phrase = message; | ||||||
| ``` | ||||||
|
|
||||||
| As a result we have two independent variables, each one storing the string `"Hello!"`. | ||||||
| Como resultado nós temos duas variáveis independentes, cada uma armazenando uma string `"Hello!".` | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
|  | ||||||
|
|
||||||
| Quite an obvious result, right? | ||||||
| Um resultado bastante óbvio, certo? | ||||||
|
|
||||||
| Objects are not like that. | ||||||
| Objetos não são assim. | ||||||
|
|
||||||
| **A variable assigned to an object stores not the object itself, but its "address in memory" -- in other words "a reference" to it.** | ||||||
| **Uma variável que foi atribuida um objeto armazena não apenas o próprio objeto, mas seu "endereço em memória" - em outras palavras "uma referência" a ele** | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| Let's look at an example of such a variable: | ||||||
| Vejamos um exemplo de tal variável: | ||||||
|
|
||||||
| ```js | ||||||
| let user = { | ||||||
| name: "John" | ||||||
| }; | ||||||
| ``` | ||||||
|
|
||||||
| And here's how it's actually stored in memory: | ||||||
| E aqui está como ele é realmente armazenado na memória: | ||||||
|
|
||||||
|  | ||||||
|
|
||||||
| The object is stored somewhere in memory (at the right of the picture), while the `user` variable (at the left) has a "reference" to it. | ||||||
| O objeto é armazenado em algum lugar na memória (figura a direita), enquanto a variável `user` (figura a esquerda) possui uma "referência" para ele. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| We may think of an object variable, such as `user`, as like a sheet of paper with the address of the object on it. | ||||||
| Nós podemos pensar em uma variável objeto, como no exemplo `user`, como uma folha de papel com o endereço do objeto nela. | ||||||
|
|
||||||
| When we perform actions with the object, e.g. take a property `user.name`, the JavaScript engine looks at what's at that address and performs the operation on the actual object. | ||||||
| Quando realizamos ações com o objeto, por exemplo pegar a propriedade `user.name`, a engine do JavaScript olha para o que tem naquele endereço e realiza a operação no próprio objeto. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| Now here's why it's important. | ||||||
| Agora aqui está o motivo da importância. | ||||||
|
|
||||||
| **When an object variable is copied, the reference is copied, but the object itself is not duplicated.** | ||||||
| **Quando uma variável objeto é copiada, a referência é copiada, mas o próprio objeto não é duplicado.** | ||||||
|
|
||||||
| For instance: | ||||||
| Por exemplo: | ||||||
|
|
||||||
| ```js no-beautify | ||||||
| let user = { name: "John" }; | ||||||
|
|
||||||
| let admin = user; // copy the reference | ||||||
| let admin = user; // cópia por referência | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| ``` | ||||||
|
|
||||||
| Now we have two variables, each storing a reference to the same object: | ||||||
| Agora temos duas variáveis, cada uma armazenando a referência para o mesmo objeto: | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
|  | ||||||
|
|
||||||
| As you can see, there's still one object, but now with two variables that reference it. | ||||||
| Como você pode ver, ainda há um objeto, porém com duas variáveis referênciando ele. | ||||||
|
|
||||||
| Podemos usar qualquer uma das variáveis para acessar o objeto e modificar seu conteúdo: | ||||||
|
|
||||||
| We can use either variable to access the object and modify its contents: | ||||||
|
|
||||||
| ```js run | ||||||
| let user = { name: 'John' }; | ||||||
|
|
||||||
| let admin = user; | ||||||
|
|
||||||
| *!* | ||||||
| admin.name = 'Pete'; // changed by the "admin" reference | ||||||
| admin.name = 'Pete'; // alterado pela referência de "admin" | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| */!* | ||||||
|
|
||||||
| alert(*!*user.name*/!*); // 'Pete', changes are seen from the "user" reference | ||||||
| alert(user.name); // 'Pete', mudanças são vistas pela referência de "user" | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| ``` | ||||||
|
|
||||||
| It's as if we had a cabinet with two keys and used one of them (`admin`) to get into it and make changes. Then, if we later use another key (`user`), we are still opening the same cabinet and can access the changed contents. | ||||||
| É como se tivéssemos um gabinete com duas chaves e usamos uma delas (`admin`) para acessa-lo e fazer mudanças. Então, se mais tarde usarmos a outra chave (`user`), ainda iremos estar abrindo o mesmo gabinete e podemos acessar os conteúdos alterados. | ||||||
|
|
||||||
| ## Comparison by reference | ||||||
| ## Comparações por referência | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| Two objects are equal only if they are the same object. | ||||||
| Dois objetos são iguais apenas se eles são o mesmo objeto. | ||||||
|
|
||||||
| For instance, here `a` and `b` reference the same object, thus they are equal: | ||||||
| Por exemplo, aqui `a` e `b` referênciam o mesmo objeto, então eles são iguais: | ||||||
|
|
||||||
| ```js run | ||||||
| let a = {}; | ||||||
| let b = a; // copy the reference | ||||||
| let b = a; // cópia por referência | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| alert( a == b ); // true, both variables reference the same object | ||||||
| alert( a === b ); // true | ||||||
| alert( a == b ); // verdade, ambas variáveis referênciam o mesmo objeto | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| alert( a === b ); // verdade | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| ``` | ||||||
|
|
||||||
| And here two independent objects are not equal, even though they look alike (both are empty): | ||||||
| E aqui dois objetos independentes não são iguais, embora sejam parecidos (ambos são vazios): | ||||||
|
|
||||||
| ```js run | ||||||
| let a = {}; | ||||||
| let b = {}; // two independent objects | ||||||
| let b = {}; // dois objetos independentes | ||||||
|
|
||||||
| alert( a == b ); // false | ||||||
| alert( a == b ); // falso | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| ``` | ||||||
|
|
||||||
| For comparisons like `obj1 > obj2` or for a comparison against a primitive `obj == 5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons are needed very rarely -- usually they appear as a result of a programming mistake. | ||||||
| Para comparações como `obj1 > obj2` ou para comparações com um primitivo `obj == 5`, objetos são convertidos para primitivos. Iremos estudar como conversões de objetos funcionam muito em breve, mas para falar a verdade, tais comparações são raramente necessárias - normalmente elas aparecem como resultado de um erro de programação. | ||||||
|
|
||||||
| ## Cloning and merging, Object.assign [#cloning-and-merging-object-assign] | ||||||
| ## Clonando e fundindo, Object.assign | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| So, copying an object variable creates one more reference to the same object. | ||||||
| Então, copiar uma varíavel objeto cria mais uma referência para o mesmo objeto. | ||||||
|
|
||||||
| But what if we need to duplicate an object? Create an independent copy, a clone? | ||||||
| Mas e se precisarmos duplicar um objeto? Criar uma cópia independente, um clone? | ||||||
|
|
||||||
| That's also doable, but a little bit more difficult, because there's no built-in method for that in JavaScript. But there is rarely a need -- copying by reference is good most of the time. | ||||||
| Isso também é factível, mas um pouco mais difícil, porque não há nenhum método embutido para isso no JavaScript. Mas a necessidade é rara - copiar por referência é o suficiente na maiorias das vezes. | ||||||
|
|
||||||
| But if we really want that, then we need to create a new object and replicate the structure of the existing one by iterating over its properties and copying them on the primitive level. | ||||||
| Mas se realmente quisermos isso, então precisamos criar um novo objeto e replicar a estrutura do objeto existente iterando por suas propriedades e copiando elas de um jeito primitivo. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| Like this: | ||||||
| Tipo assim: | ||||||
|
|
||||||
| ```js run | ||||||
| let user = { | ||||||
|
|
@@ -119,59 +119,59 @@ let user = { | |||||
| }; | ||||||
|
|
||||||
| *!* | ||||||
| let clone = {}; // the new empty object | ||||||
| let clone = {}; // o novo objeto vazio | ||||||
|
|
||||||
| // let's copy all user properties into it | ||||||
| // vamos copiar todas as propriedades de user para ele | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| for (let key in user) { | ||||||
| clone[key] = user[key]; | ||||||
| } | ||||||
| */!* | ||||||
| */!* | ||||||
|
|
||||||
| // now clone is a fully independent object with the same content | ||||||
| clone.name = "Pete"; // changed the data in it | ||||||
| // agora clone é um objeto totalmente independente com o mesmo conteúdo | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| clone.name = "Pete"; // alterada a informação nele | ||||||
|
|
||||||
| alert( user.name ); // still John in the original object | ||||||
| alert( user.name ); // ainda John no objeto original | ||||||
| ``` | ||||||
|
|
||||||
| Also we can use the method [Object.assign](mdn:js/Object/assign) for that. | ||||||
| Também podemos usar o método [Object.assign](mdn:js/Object/assign) para isso. | ||||||
|
||||||
| Também podemos usar o método [Object.assign](mdn:js/Object/assign) para isso. | |
| Também podemos usar o método [Object.assign](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) para isso. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| - Argumentos adicionais `fonte1, ..., fonteN` (pode ser quantos precisar) são os objetos fonte. | |
| - Argumentos adicionais `fonte1, ..., fonteN` (podem ser quantos precisar) são os objetos fonte. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| - Ele copia as propriedades de todos os objetos fontes `fonte1, ..., fonteN` para o destino `dest`. Em outras palavras, propriedaes de todos os argumentos começando pelo segundo são copiadas para o primeiro objeto. | |
| - Ele copia as propriedades de todos os objetos fontes `fonte1, ..., fonteN` para o destino `dest`. Por outras palavras, as propriedaes de todos os argumentos começando pelo segundo são copiadas para o primeiro objeto. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Podemos também utilizar `Object.assign` para substituir `for..in` loop para clonagem simples: | |
| Podemos também utilizar `Object.assign` para substituir o ciclo `for..in` para clonagem simples: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, you may also leave 'loop' without translation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Também há outros métodos para clonagem de objeto, por exemplo usando a [sintaxe espalhada](info:rest-parameters-spread) `clone = {...user}`, coberto mais tarde no tutorial. | |
| Também há outros métodos para clonagem de objeto, por exemplo usando a [sintaxe espalhada](info:rest-parameters-spread) `clone = {...user}`, coberta mais tarde no tutorial. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Ate agora assumimos que todas as propriedades de `user` são primitivas. Mas propriedades podem ser referências para outros objetos. O que fazer com essas propriedades? | |
| Até agora assumimos que todas as propriedades de `user` são primitivas. Mas propriedades podem ser referências para outros objetos. O que fazer com essas propriedades? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| alert( user.sizes === clone.sizes ); // verdade, mesmo objeto | |
| alert( user.sizes === clone.sizes ); // true (verdade), mesmo objeto |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| user.sizes.width++; // altera a propriedade por um | |
| user.sizes.width++; // altere a propriedade em um lugar |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| alert(clone.sizes.width); // 51, olhe o outro resultado | |
| alert(clone.sizes.width); // 51, veja o resultado no outro |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Para concertar isso, precisamos usar um ciclo de clonagem para examinar cada valor de `user[key]` e, se for um objeto, então replicar também sua estrutura. Isso é chamado de "clonagem profunda". | |
| Para concertar isso, precisamos usar um ciclo de clonagem para examinar cada valor de `user[key]` e, se for um objeto, então replicar também a sua estrutura. Isso é chamado de "clonagem profunda". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ````smart header="Const objects can be modified" | |
| ````smart header="Objetos constantes podem ser modificados" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Um efeito colateral importante de armazenar objetos como referência é que objetos declarados como `const` podem ser modificados. | |
| Um efeito colateral importante de armazenar objetos como referência é que objetos declarados como `const` *podem* ser modificados. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Pode parecer que a linha (*) causaria um erro, mas não causa. O valor de `user` é constante, precisa sempre referenciar o mesmo objeto, mas propriedades desse objeto são livres para serem alteradas. | |
| Pode parecer que a linha (*) causaria um erro, mas não causa. O valor de `user` é constante, precisa de sempre referenciar o mesmo objeto, mas propriedades desse objeto são livres de serem alteradas. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Dito isso, se realmente precisarmos criar propriedades constantes no objeto, também é possível, mas usando métodos totalmente diferentes. Iremos menconar isso no capítulo <info:property-descriptors>. | |
| Dito isso, se realmente precisarmos de criar propriedades constantes no objeto, também é possível, mas usando métodos totalmente diferentes. Iremos menconar isso no capítulo <info:property-descriptors>. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Objetos são atribuidos e copiados por referência. Em outras palavras, uma variável armazena não o "valor do objeto", mas sim sua "referência" (endereço na memória) para o valor. Então copiar tal variável ou passar ela como um argumento de uma função copia a referência, não o proprio objeto. | |
| Objetos são atribuidos e copiados por referência. Por outras palavras, uma variável armazena não o "valor do objeto", mas sim uma "referência" (endereço na memória) para o valor. Então copiar tal variável ou passar ela como um argumento de uma função copia a referência, não o proprio objeto. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Todas as operações por meio de referências copiadas(como adicionar/remover propriedades) são realizadas no mesmo objeto único. | |
| Todas as operações por meio de referências copiadas(como adicionar/remover propriedades) são realizadas no mesmo único objeto. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Para criar uma "cópia real" (um clone) podemos usar `Object.assign` para o então chamado "cópia superficial" (objetos aninhados são copiados por referência) ou uma função de "clonagem profunda", como a [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep). | |
| Para criar uma "cópia real" (um clone) podemos usar `Object.assign` para a chamada "cópia superficial" (objetos aninhados são copiados por referência) ou uma função de "clonagem profunda", como a [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep). |
Uh oh!
There was an error while loading. Please reload this page.