aboutsummaryrefslogtreecommitdiff
path: root/files/pt-br/web/javascript/reference/statements/with/index.html
blob: aec9437adadf1d7e4331556917f20e64b90e6d5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
---
title: with
slug: Web/JavaScript/Reference/Statements/with
tags:
  - Declaração
  - Deprecado
  - Deprecated
  - JavaScript
  - Statement
translation_of: Web/JavaScript/Reference/Statements/with
---
<div class="warning">O uso da declaração <code>with</code> não é recomendado, isso porque ele pode ser a fonte de bugs confusos e problemas de compatibilidade. Veja o parágrafo "Contra de ambiguidade" na seção "Descrição" para mais detalhes.</div>

<div>{{jsSidebar("Statements")}}</div>

<p>A <strong>declaração with</strong> extende a cadeia de escopo para uma declaração.</p>

<h2 id="Sintaxe">Sintaxe</h2>

<pre class="syntaxbox">with (expressão)
  <em>declaração</em>
</pre>

<dl>
 <dt><code>expressão</code></dt>
 <dd>Adiciona a dada expressão à cadeia de escopo quando estiver avaliando a declaração. O parênteses em volta da expressão é obrigatório.</dd>
 <dt><code>declaração</code></dt>
 <dd>Qualquer declaração. Para executação multiplas declarações, utilize a declaração em <a href="/en-US/docs/Web/JavaScript/Reference/Statements/block" title="JavaScript/Reference/Statements/block">bloco</a> ({ ... }) para agrupar estas declarações.</dd>
</dl>

<h2 id="Descrição">Descrição</h2>

<p>JavaScript procura por um nome não qualificado procurando uma cadeia de escopo associada à execução do contexto do script ou função contendo um nome não qualificado. A declaração 'with' adiciona o dado objeto à frenet dessa cadeia de escopo durante a validação desse corpo de declarações. Se um nome não qualificado usado no corpo for igual ao de uma propriedade na cadeia de escopo,  então o nome ficará ligado à propriedade e ao objeto contendo a propriedade. Senão, um {{jsxref("ReferenceError")}} será invocado.</p>

<div class="note">Usar <code>with</code> não é recomendado, e está probido no <a href="/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode" title="JavaScript/Strict mode">strict mode</a> do ECMAScript 5. A alternativa recomendada é atribuir o objeto cujas propriedades você quer acessar a uma variável temporária.</div>

<h3 id="Pros_contras_de_perfomance">Pros &amp; contras de perfomance</h3>

<p><strong>Pro:</strong> A declaração <code>with</code> pode ajudar o tamanho do arquivo por reduzir a necessidade de repetir a referência a um objeto longo sem penalidade na perfomance. A cadeia de escopo mudada por um 'with' não é computacionalmente cara. O uso de 'with' irá aliviar o interpretador de tratar repetidamente as referências. Note que, no entando, isso em muitos casos pode ser substituído usando uma variável temporária para armazenar a referência do objeto desejado.</p>

<p><strong>Contra:</strong> A declaração <code>with</code> força que o objeto especifícado a ser procurado primeiro por pesquisas de nome. Assim sendo, todos os indentificadores que não são membros do objeto espeficícado vão ser encontrados mais lentamente em um bloco 'with'. Onde a perfomance é importande, 'with' deve ser usado apenas para englobar blocos de código que acessam membros de um objeto especifíco.</p>

<h3 id="Contra_de_ambiguidade">Contra de ambiguidade</h3>

<p><strong>Contra:</strong> A declaração <code>with</code> faz ser difícil para um leitor humano ou compilador JavaScript decidir se um nome não qualificado var se encontrado em uma cadeia de escopo, e também, em qual objeto. Dado o exemplo seguinte:</p>

<pre class="brush: js">function f(x, o) {
  with (o) {
    console.log(x);
  }
}</pre>

<p>Apenas quando <code>f</code> é chamado é <code>x</code> ou encontrado ou não, e se for encontrado, ou em <code>o</code> ou (se nenhuma propriedade existir) no objeto de ativação de <code>f</code>, onde o nome de <code>x</code> é o primeiro argumento formal. Se você esquecer de definir <code>x</code> no objeto que você passou como segundo argumento, ou se há algum bug similar ou confusão, você não vai receber um erro -- apenas resultados inesperados.</p>

<p><strong>Contra: </strong>Código utilizando <code>with</code> talvez não seja compatível posteriormente, especialmente quando usado com algo que não seja um objeto simples. Considere esse exemplo:</p>

<div>
<pre class="brush:js">function f(foo, values) {
  with (foo) {
    console.log(values);
  }
}
</pre>

<p>Se você chamar <code>f([1,2,3], obj)</code> em um ambiente ECMAScript 5, então a referência de <code>values</code> dentro da declaração <code>with</code> irá ser <code>obj</code>. No entando, ECMAScript 6 introduz uma propriedade <code>values</code> no <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype">Array.prototype</a></code> (então isso estará disponível em todas as arrays). Então, em um ambiente JavaScript que suporta ECMAScript 6, a referência de <code>values</code> dentro da declaração <code>with</code> irá ser <code>[1,2,3].values</code>.</p>
</div>

<h2 id="Exemplos">Exemplos</h2>

<h3 id="Usando_with">Usando <code>with</code></h3>

<p>A seguinte declaração <code>with</code> irá especificar que o objeto <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math" title="JavaScript/Reference/Global_Objects/Math"><code>Math</code></a> é o objeto padrão. As seguintes declarações seguindo a declaração <code>with</code> irão referir a propriedade <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/PI" title="JavaScript/Reference/Global_Objects/Math/PI"><code>PI</code></a> e aos métodos <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos" title="JavaScript/Reference/Global_Objects/Math/cos"><code>cos</code></a><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sin" title="JavaScript/Reference/Global_Objects/Math/sin"><code>sin</code></a>, sem especificar um objeto. JavaScript assume o objeto <code>Math</code> para essas referências.</p>

<pre class="brush:js">var a, x, y;
var r = 10;

with (Math) {
  a = PI * r * r;
  x = r * cos(PI);
  y = r * sin(PI / 2);
}</pre>

<h2 id="Especificações">Especificações</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Especificação</th>
   <th scope="col">Situação</th>
   <th scope="col">Comentário</th>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-with-statement', 'with statement')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-with-statement', 'with statement')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-12.10', 'with statement')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td>Agora proibido no modo estrito.</td>
  </tr>
  <tr>
   <td>{{SpecName('ES3', '#sec-12.10', 'with statement')}}</td>
   <td>{{Spec2('ES3')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td>{{SpecName('ES1', '#sec-12.10', 'with statement')}}</td>
   <td>{{Spec2('ES1')}}</td>
   <td>Definição inicial</td>
  </tr>
 </tbody>
</table>

<h2 id="Browser_compatibility">Compatibilidade com navegadores</h2>

<p>{{CompatibilityTable}}</p>

<div id="compat-desktop">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Chrome</th>
   <th>Edge</th>
   <th>Firefox (Gecko)</th>
   <th>Internet Explorer</th>
   <th>Opera</th>
   <th>Safari</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
  </tr>
 </tbody>
</table>
</div>

<div id="compat-mobile">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Android</th>
   <th>Chrome for Android</th>
   <th>Edge</th>
   <th>Firefox Mobile (Gecko)</th>
   <th>IE Mobile</th>
   <th>Opera Mobile</th>
   <th>Safari Mobile</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
  </tr>
 </tbody>
</table>
</div>

<h2 id="Veja_também">Veja também</h2>

<ul>
 <li>{{jsxref("Statements/block", "block")}}</li>
 <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode">Strict mode</a></li>
 <li>{{jsxref("Symbol.unscopables")}}</li>
 <li>{{jsxref("Array.@@unscopables", "Array.prototype[@@unscopables]")}}</li>
</ul>