aboutsummaryrefslogtreecommitdiff
path: root/files/pl/web/javascript/reference/operators/nullish_coalescing_operator/index.html
blob: 67e33b14738140a10ef3279826fd0c4dcd3e3afc (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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
---
title: Operator null'owego scalania (??)
slug: Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
tags:
  - JavaScript
  - Language feature
  - Operator
  - Reference
  - nullish coalescing
translation_of: Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
original_slug: Web/JavaScript/Referencje/Operatory/Nullish_coalescing_operator
---
<p>{{JSSidebar("Operators")}}</p>

<p><strong>Operator null'owego scalania (<code>??</code>)</strong> - to operator logiczny, stosowany w wyrażeniach, który zwraca to co jest po jego lewej stronie, tak długo, jak to nie jest <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/null">null</a></code>, albo <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined">undefined</a></code>, wtedy zwraca to, co jest po prawej.</p>

<div class="blockIndicator note">
<p>Początkowo ewaluowane jest tylko wyrażenie z lewej strony.<br>
 Dopiero, gdy zachodzi taka potrzeba, ewaluowane jest prawe wyrażenie.</p>
</div>

<p>Jest podobny do <strong>logicznego operatora LUB (<code>||</code>)</strong><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR">Logical OR (||)</a> ), ale <strong>LUB</strong> decyduje o tym, czy wziąć prawą wartość, na innej podstawie:<br>
 <em>Czy lewa wartość jest fałszopodobna</em> (<a href="/en-US/docs/Glossary/Falsy">Falsy</a>)<em>?</em><br>
 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/null">null</a></code> i <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined">undefined</a></code> są fałszopodobne, ale sęk w tym, że nie tylko one, ale również np. <code>0</code>, czy <code>""</code>. Czasem nie chce się podmieniać niczego za <code>0</code> i <code>""</code>, uważając je za dopuszczalne wartości.<br>
 Wtedy właśnie przydaje się ten operator.</p>

<div>{{EmbedInteractiveExample("pages/js/expressions-nullishcoalescingoperator.html")}}</div>

<p class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.<br>
 See <a href="https://github.com/mdn/interactive-examples/pull/1482#issuecomment-553841750">PR #1482</a> regarding the addition of this example.</p>

<h2 id="Składnia">Składnia</h2>

<pre class="syntaxbox notranslate"><u>LWyr</u> ?? <u>PWyr</u></pre>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Pole</th>
   <th scope="col">Opis</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>LWyr</td>
   <td>Wyrażenie główne, ewaluowane na początku.<br>
    Jeżeli jego wartość wynikowa jest <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/null">null</a></code>, albo <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined">undefined</a></code>, to nie ona zostanie zwrócona, ale wartość wynikowa wyrażenia <u>PWyr</u></td>
  </tr>
  <tr>
   <td>PWyr</td>
   <td>Wyrażenie zamienne, ewaluowane, kiedy wartość <u>LWyr</u> jest <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/null">null</a></code>, albo <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined">undefined</a></code>.</td>
  </tr>
 </tbody>
</table>

<h2 id="Przykłady"><span style="">Przykłady</span></h2>

<h3 id="Użycie_operatora">Użycie operatora</h3>

<p>W tym przykładzie użyjemy <strong>operatora null'owego scalania</strong> do podania zapasowych wartości, przy inicjowaniu stałych:</p>

<pre class="brush: js notranslate">const wartoscNull = null;
const warA = wartoscNull ?? "domyślne dla A";
console.log(warA);

// konsola: "domyślne dla A"



const pustyTekst = "";   // fałszopodobny
const warB = pustyTekst ?? "domyślne dla B";
console.log(warB);

// konsola: ""
// ponieważ "??" reaguje tylko konkretnie na null albo undefined



const jakasLiczba = 42;
const warC = jakasLiczba ?? 0;
console.log(warC);

// konsola: 42</pre>

<h3 id="Porównanie_działania_i">Porównanie działania "??" i "||"</h3>

<p>Wcześniej przed pojawieniem się tego operatora, używano <strong>LUB (<code>||</code>) (<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR">Logical OR (||)</a>)</strong>:</p>

<pre class="notranslate">let liczba;
let zabezpLicz = liczba || 1;
// zmienna "wejscie" nie była nigdy zapełniona żadną wartością,
// więc była "undefined", a undefined jest fałszopodobne, więc
// JavaScript wziął zapasowe '1'.

console.log(2 * zabezpLicz);
// konsola: 2
</pre>

<p>To działa, ale...<br>
 przez to jakim operatorem jest <strong>LUB</strong>, nie tylko <code>undefined</code> zostanie tu zamienione, ale też i <code>0</code>, które, w kontekście tego przykładu, powiedzmy, że jest wartością, która powinna być ok:</p>

<pre class="brush: js notranslate">let liczba = 0;
let zabezpLicz = liczba || 1;
// zmienna "wejscie" została zapełniona zerem, ale jest fałszopodobne,
//więc JavaScript wziął zapasowe '1'.

console.log(2 * zabezpLicz);
// konsola: 2
// chcieliśmy: 0
</pre>

<p>Operator null'owego scalania rozwiązuje ten problem:</p>

<pre class="brush: js notranslate">let liczba = 0;
let zabezpLicz = liczba ?? 1;
// zmienna "wejscie" została zapełniona zerem,
//mimo tego, że jest fałszopodobne, "??" akceptuje je, bo to nie null, ani undefined, i
//JavaScript zostawia '0'.

console.log(2 * zabezpLicz);
// konsola: 0
</pre>

<h3 id="Pomijanie_ewaluacji">Pomijanie ewaluacji</h3>

<p>Podobnie jak inne operatory logiczne <strong>LUB (<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR" style="">Logical OR (||)</a>)</strong> i <strong>I (<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND">Logical AND (&amp;&amp;)</a>)</strong>, ten operator rozpoczyna od ewaluacji wyrażenia po lewej stronie, i dopiero gdy trzeba, zajmuje się prawą stroną:</p>

<pre class="brush: js notranslate">function A(){
  console.log("Tu A!");
  return false;
}
function B(){
  console.log("Tu B!");
  return true;
}

if( A() ?? B() ) console.log("Otrzymano 'true'");
else console.log("Otrzymano 'false'");
// konsola: "Otrzymano 'false'"
</pre>

<p>i :</p>

<pre class="brush: js notranslate">function A(){
  console.log("Tu A!");
  return null; // teraz tu jest zwracany null, na który reaguje "??"
}
function B(){
  console.log("Tu B!");
  return true;
}

if( A() ?? B() ) console.log("Otrzymano 'true'");
else console.log("Otrzymano 'false'");
// konsola: "Otrzymano 'true'"</pre>

<h3 id="Nie_działa_seryjnie_ani_z_LUB_ani_z_I">Nie działa seryjnie, ani z LUB, ani z I</h3>

<p>W wyrażeniach, nie można stawiać zwyczajnie <strong>operatora null'owego scalania</strong> w otoczeniu operatorów <strong>LUB</strong> i <strong>I</strong>, mimo ustalonej kolejności wykonywania działań. Będzie to odbierane jako błąd składniowy:</p>

<pre class="brush: js example-bad notranslate">null || undefined ?? "yyy..."; // to będzie SyntaxError
true || undefined ?? "aha.";   // to też będzie SyntaxError
//bo tu chodzi o to, że jest "||" i "??" razem, nie o wartości.
</pre>

<p>Trzeba je rozdzielić nawiasami:</p>

<pre class="brush: js example-good notranslate">(null || undefined) ?? "yyy...";  // zwraca: "yyy..."
null || (undefined ?? "działa!"); // zwraca: "działa!"
</pre>

<h3 id="Odniesienie_do_Operatora_opcjonalnego_dostępu_.">Odniesienie do Operatora opcjonalnego dostępu "?."</h3>

<p>Sposób w który <strong>operator null'owego scalania</strong> pracuje z wartościami <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/null" style="">null</a></code> i <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined">undefined</a></code>, jest intuicyjny analogicznie u <strong>operatora opcjonalnego dostępu</strong> (<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining">Optional chaining (?.)</a>, i razem pozwalają na ciekawe akcje, np.:</p>

<pre class="notranslate">class objekt{
  tekst;

  constructor(tekst = null){
    this.tekst = tekst;
  }

  odczytTekst(){
    return this.tekst;
  }
  wpisTekst(w){
    this.tekst = w;
    return true;
  }
}

let objekty = [new objekt("cześć!"), null, new objekt()];



// zadanie kodu: zamień tekst'y w objekt'ach na duże litery,
// używając funkcji dostępu, a pozostawiając puste wartości
// bez zmian


// wersja typeof
for(let i = 0; i &lt; objekty.length; i++)
  if(typeof(objekty[i]) == "object")
    if(typeof(objekty[i].odczytTekst()) == "string")
      objekty[i].wpisTekst(objekty[i].odczytTekst().toUpperCase());


// wersja operatorów "??" i "?."
for(let i = 0; i &lt; objekty.length; i++)
  objekty[i]?.wpisTekst(objekty[i]?.odczytTekst()?.toUpperCase() ?? null);

console.log(objekty);
</pre>

<p>Czasami użycie tych operatorów upraszcza kod.<br>
 Poza tym każda funkcja jest wywoływana najwyżej raz i może to być co kolwiek.</p>

<h2 id="Specyfikacje">Specyfikacje</h2>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Specification</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{SpecName('ESDraft', '#prod-Nulli', 'nullish coalescing expression')}}</td>
  </tr>
 </tbody>
</table>

<h2 id="Wsparcie_przeglądarek">Wsparcie przeglądarek</h2>



<p>{{Compat("javascript.operators.nullish_coalescing")}}</p>

<h2 id="Zobacz_też...">Zobacz też...</h2>

<ul>
 <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining">The optional chaining operator</a></li>
 <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_OR_2">The logical OR (<code>||</code>) operator</a></li>
 <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters">Default parameters in functions</a></li>
</ul>