forked from hectorip/Eloquent-JavaScript-es
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path01_values.txt
More file actions
636 lines (521 loc) · 25.5 KB
/
01_values.txt
File metadata and controls
636 lines (521 loc) · 25.5 KB
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
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
:chap_num: 1
:prev_link: 00_intro
:next_link: 02_program_structure
:docid: values
= Valores, Tipos y Operadores =
[chapterquote="true"]
[quote, Master Yuan-Ma, The Book of Programming]
____
Debajo de la superficie de la
máquina, el programa se mueve. Sin esfuerzo, se expande y contrae.
En gran armonía, los electrones se separan y reagrupan. Las formas en
el monitor no son más que ondas en el agua. La escencia permanece
invisible debajo.
____
(((Yuan-Ma)))(((Libro de la Programación)))(((datos
binarios)))(((datos)))(((bit)))(((memoria))) En el mundo de las
computadoras sólo existen los datos. Puedes leer, modificar y crear
nuevos datos, pero cualquier cosa que no sea datos simplemente no
existe. Todos estos datos son guardados en largas secuencias de bits
y por lo tanto son parecidos.
(((CD)))(((señal))) Los bits son cualquier tipo de cosas con dos valores,
normalmente descritos como ceros y unos. Dentro de la computadora, toman
formas como alta o baja carga eléctrica, una señal débil o fuerte, o
un punto brillante u opaco en la superficie de un CD. Cualquier pieza
de información discreta puede ser reducida a una secuencia de ceros y
unos y por lo tanto representada como bits.
(((número binario)))(((base)))(((número décimal))) Por ejemplo, piensa
cómo podrías representar el número 13 en bits. Funciona de la misma
forma en que escribes números decimales, pero en vez de tener 10
((dígitos)), tienes sólo 2, y el peso de cada uno se incrementa
por un factor de 2 de derecha a izquierda. Aquí están los bits que
conforman el número 13, con los pesos de cada uno mostrados debajo de
ellos.
----
0 0 0 0 1 1 0 1
128 64 32 16 8 4 2 1
----
Así que ese es el número binario 00001101, u 8 + 4 + 1,
que equivale a 13.
== Valores ==
(((memoria)))(((alamacenamiento de datos volátil)))(((disco duro)))Imagina
un mar de bits. Un océano de estos. Una computadora moderna típica
tiene más de 30 mil millones de bits en su almacenamiento de datos
volátil. El almacenamiento no volátil (el disco duro o su equivalente)
tiene un par de órdenes de magnitud más todavía.
image::img/bit-sea.png[alt="The Ocean of Bits"]
Para ser capaz de trabajar con semejantes cantidades de bits sin perderte,
puedes separarlos en pedazos que representen piezas de información. En un
entorno en JavaScript, esos pedazos son llamados _((valor))es_. Aunque
todos los valores están hechos de bits, juegan diferentes roles. Cada
valor tiene un tipo que determina su rol. Existen seis tipos básicos de
valores en JavaScript: números, cadenas, Booleanos, objetos, funciones,
y valores indefinidos.
(((recolección de basura)))Para crear un valor, sólo tienes que invocar
su nombre. Esto es conveniente. No tienes que reuinir el material de
construcción de tus valores o pagar por ellos. Sólo llamas uno y _woosh_,
lo tienes. No son creados de la nada, por supuesto. Cada valor tiene que
estar almacenado en algún lugar, y si quieres usar una cantidad enorme
de estos al mismo tiempo, te podrías quedar sin bits. Afortunadamente,
esto se convierte en un problema sólamente si los necesitas todos al
mismo tiempo. Tan pronto como dejes de usar un valor se disipará, dejando
sus bits para que sean reciclados como material de construcción de la
próxima generación de valores.
Este capítulo introduce los elementos atómicos de los programas en
JavaScript, los tipos de valores simples y los operadores que pueden
actuar sobre tales valores.
== Números ==
(((sintaxis)))(((número)))(((número,notación)))Los valores de tipo
_número_(number) son, sin sorpresa alguna, valores numéricos.
En un programa en JavaScript, se escriben de la siguiente forma:
[source,javascript]
----
13
----
(((número binario))) Usa eso en un programa y causará que el patrón de
bits para el número 13 exista dentro de la memoria de la computadora.
(((número,representación)))(((bit)))JavaScript usa una cantidad fija
de bits, 64, para guardar un valor del tipo número. Existe un límite
en la cantidad de patrones que se pueden hacer con 64 bits, lo que
significa que la cantidad de números que puedes representar también es
limitada. Para _N_ ((dígito))s decimales, la cantidad de números que
pueden ser representados es 10^_N_^. Similarmente, dados 64 dígitos
binarios, puedes representar 2^64^ números diferentes, que es cerca de
18 cuatrillones (un 18 con 18 ceros después). Eso es mucho.
La memoria de la computadora solía ser mucho más pequeña, y la gente
tendía a usar grupos de 8 ó 16 bits para representar sus números. Era
fácil _((desbordar))_ accidentalmente números tan pequeños: terminar
con un número que no pudiera ser almacenado en el número dado de bits. Hoy,
incluso las computadoras personales tienen mucha memoria, así
que eres libre de usar grupos de 64 bits, lo que significa que
necesitas preocuparte del desbordamiento sólo cuando estés
tratando con números verdaderamente astronómicos.
(((signo)))(((número de punto flotante)))(((número fraccionario)))(((bit de signo)))No
todos los número enteros debajo de 18 cuatrillones caben en un número
de JavaScript. Esos bits también guardan números negativos, así
que un bit indica el signo del número. Un problema mayor es que
los números no enteros también deben ser representados. Para hacer esto,
algunos de los bits son usados para guardar la posición del punto decimal.
El número entero máximo real que puede ser guardado está más cerca del rango de
los 9 trillones (15 ceros), que aún es satisfactoriamente grande.
(((number,notación)))Los números fraccionarios son escritos usando un punto.
[source,javascript]
----
9.81
----
(((exponente)))(((notación científica)))(((número,notación)))Para números
muy grandes o muy pequeños, también se puede usar la notación
científica, añadiendo una "e" de "exponente", seguido por el exponente
del número:
[source,javascript]
----
2.998e8
----
Esto es 2.998 × 10^8^ = 299,800,000.
(((pi)))(((número, precisión de)))(((número de punto flotante)))Cálculos con
números enteros (en inglés llamados _((integer))_) más pequeños que el supracitado
9 trillones, están garantizados para siempre ser precisos. Desafortunadamente,
cálculos con números fraccionarios generalmente no lo son. Justo como π (pi)
no puede ser expresado precisamente por un número finito de dígitos decimales,
muchos números pierden algo de precisión cuando sólo hay 64 bits disponibles
para guardarlos. Esto es una pena, pero causa problemas prácticos sólo en
algunas situaciones específicas. Lo importante es estar al tanto de
esto y tratar a los números digitales fraccionarios como aproximaciones
y no como valores precisos.
=== Aritmética ===
(((sintaxis)))(((operador)))(((operador
binario)))(((aritmética)))(((adición)))(((multiplicación)))Lo principal que
se hace con los números es la aritmética. Las operaciones aritméticas
como la suma o la multiplicación toman dos valores y producen uno
nuevo a partir de estos. Así es como lucen en JavaScript:
[source,javascript]
----
100 + 4 * 11
----
(((operador,applicación)))(((asterisco)))(((símbolo
más)))(((operador pass:[*])))(((operador +))) Los símbolos `+` y `*`
son llamados _operadores_. El primero representa la suma y el segundo
la multiplicación. Al poner un operador entre dos valores, se
aplicará la operación a esos valores y producirá un nuevo valor.
(((agrupamiento)))(((paréntesis)))(((precedencia)))¿Significa el ejemplo
anterior: "suma 4 y 100, y multiplica el resultado por 11", o es la
multiplicación ralizada antes de hacer la suma? Como pudiste haber adivinado,
la multiplicación ocurre primero. Pero como en matemáticas, puedes cambiar
esto mediante encerrar en paréntesis la suma.
[source,javascript]
----
(100 + 4) * 11
----
(((carácter guión)))(((diagonal
)))(((división)))(((resta)))(((menos)))(((operador
-)))(((operador /)))Para la resta existe el operador `-`,
y la división se puede hacer con el operador `/`.
Cuando los operadores aparecen juntos sin paréntesis, el orden en el que
son aplicados es determinado por su _((precedencia))_. El ejemplo muestra
que la multiplicación se aplica antes que la suma. El operador `/` tiene
la misma precedencia que `*`. De igual forma pasa con `+` y `-`. Cuando
varios operadores con la misma precedencia aparecen juntos, como en
`1 - 2 + 1`, son aplicados de izquierda a derecha: `(1 - 2) + 1`.
Estas reglas de precedencia son algo de lo que no te deberías
de preocupar. Cuando tengas duda, simplemente agrega paréntesis.
(((operador módulo)))(((división)))(((operador sobrante)))(((operador
%)))Existe un operador aritmético más, que podrías no reconocer
inmediatamente. El símbolo `%` es usado para representar la
operación _sobrante_. `X % Y` es el sobrante de dividir `X` entre
`Y`. Por ejemplo, `314 % 100` produce `14`, y `144 % 12` da `0`.
La precedencia del sobrante es la misma que la de la multiplicación
y división. Verás a menudo este operador referido como _módulo_,
aunque técnicamente _sobrante_ es más preciso.
=== Números Especiales ===
(((número,valores especiales)))Hay tres valores especiales en JavaScript
que son considerados números pero no se comportan como números
normales.
(((infinito)))Los primeros dos son `Infinity` y `-Infinity`, que
representan infinitos positivos y negativos. `Infinity - 1`
sigue siendo `Infinity`, y así por el estilo. No confíes mucho en los
cálculos basados en infinitos. No son matemáticamente confiables y
pronto te llevarán al próximo número especial: `NaN`.
(((NaN)))(((not a number)))(((divisón por cero)))`NaN` son las siglas
de “not a number” ("no es un número"), aunque es un valor del tipo
número. Obtendrás este resultado cuando, por ejemplo, trates de
calcular `0 / 0` (cero entre cero), `Infinity - Infinity`, o cualquier
otra operación numérica que no produzca un resultado
preciso, significativo.
== Cadenas ==
(((sintaxis)))(((texto)))(((carácter)))(((cadena,notación)))(((carácter
comilla simple)))(((carácter comilla doble)))(((comillas)))El siguiente
tipo de dato básico son las _cadenas_. Estas son usadas para representar
texto. Son declaradas al poner el contenido entre comillas.
[source,javascript]
----
"Parcha mi bote con goma de mascar"
'Monkeys wave goodbye'
----
Tanto las comillas simples como las dobles pueden ser usadas para declarar
cadenas de texto mientras coincidan al principio y al final.
(((salto de línea)))(((caracter de nueva línea)))(((newline)))Casi cualquier
cosa puede estar entre comillas, y JavaScript creará una cadena. Pero unos
cuantos caracteres son un poco difíciles. Puedes imaginar que poner
comillas dentro de comillas puede ser difícil. _Newlines_ (el carácter
salto de línea, lo que obtines cuando presionas Enter), tampoco puede
ser introducido entre comillas. La cadena tiene que permanecer en una
sola línea.
(((escape,en cadenas)))(((diagonal invertida)))Para hacer posible
la inclusión de estos caracteres en una cadena de texto, la siguiente
notación es usada: cuando una diagonal invertida(_backslash_: `\`)
se encuentra dentro de un texto entre comillas, indica que el carácter
siguiente tiene un significado especial. Esto es llamado _escapar_ el
carácter. Una comilla que es precedida por una diagonal invertida
no terminará la cadena, sino que será parte de ella. Cuando un
carácter `n` sigue a una diagonal invertida, se interpreta como
una nueva línea. Similarmente, un `t` después de la diagonal invertida
significa un ((tabulador)). Tomemos la siguiente cadena:
[source,javascript]
----
"Esta es la primera línea\nY esta la segunda"
----
El verdadero texto contenido es:
----
Esta es la primera línea
Y esta la segunda
----
Existen, por supuesto, situaciones en las que querrás que una
diagonal invertida sea sólo eso en una cadena de texto, no un
código especial. Si dos diagonales invertidas están juntas, se volverán
una, y sólo eso quedará como resultado en el valor de la cadena.
Así es como la cadena "++Un carácter de nueva línea es escrito "\n".++"
puede ser expresada:
[source,javascript]
----
"Un carácter de nueva línea es escrito \"\\n\"."
----
(((operador +)))(((concatenación)))Las cadenas de texto no pueden ser
divididas numéricamente, multiplicadas, o restadas, pero el carácter
`+` _puede_ ser usado en ellas. No suma, sino que _concatena_; pega dos
cadenas. La siguiente línea produce la cadena `"concatenar"`:
[source,javascript]
----
"con" + "cat" + "e" + "nar"
----
Hay más maneras de manipular las cadenas, de las que hablaremos cuando
lleguemos a los métodos en el link:04_data.html#methods[Capítulo 4].
== Operadores Unitario ==
(((operador)))(((operador typeof)))(((tipo)))No todos los operadores
son símbolos. Algunos son escritos como palabras. Un ejemplo es el
operador `typeof`, que produce una cadena de texto que representa el
tipo del valor que le pasaste.
[source,javascript]
----
console.log(typeof 4.5)
// → number
console.log(typeof "x")
// → string
----
[[console.log]]
(((console.log)))(((salida)))(((consola de JavaScript)))Usaremos
`console.log` para indicar que queremos ver el resultado de la evaluación
de algo. Cuando corres ese código, el valor producido debería mostrarse en
pantalla, aunque la forma en que aparece dependerá del entorno en que
estés corriendo el programa.
(((negación)))(((operador -)))(((operador binario)))(((operador
binario))) Los otros operadores que hemos visto operaban sobre
dos valores, pero `typeof` sólamente toma uno. Los operadores que usan
dos valores son llamados operadores _binarios_, mientras que aquellos
que sólo toman uno son llamados operadores _unitarios_. El operador menos
puede usar tanto como operador binario como operador unitario.
[source,javascript]
----
console.log(- (10 - 2))
// → -8
----
== Valores Booleanos ==
(((Booleano)))(((operador)))(((true)))(((false)))(((bit)))A menudo,
necesitarás un valor que simplemente distinga entre dos posibilidades,
como "sí" y "no" o "encendido" y "apagado". Para esto, JavaScript
tiene un tipo _Booleano_, que tiene sólo dos valores, verdadero (true)
y falso (false), que son simplemente estas palabras en inglés.
=== Comparaciones ===
(((compración)))Esta es una forma de producir valores booleanos:
[source,javascript]
----
console.log(3 > 2)
// → true
console.log(3 < 2)
// → false
----
(((comparación,de números)))(((operador >)))(((operador <)))(((mayor
que)))(((menor que)))Los signos `>` y `<` son los símbolos tradicionales
para "es mayor que" y "es menor que", respectivamente. Estos son
operadores binarios. Aplicarlos resulta en un valor Booleano que indica
si son ciertos en ese caso.
Las cadenas de texto pueden ser comparadas de la misma manera.
[source,javascript]
----
console.log("Aardvark" < "Zoroaster")
// → true
----
(((comparación,de cadenas)))La manera en que las cadenas son ordenadas
es más o menos alfabética: las letras mayúsculas son siempre "menores"
que las minúsculas, así que `"Z" < "a"` es verdad, y los caracteres no
alfabéticos (!, -, y así por el estilo) son también incluidos en el
ordenamiento. La comparación real está basada en el estándar
_((Unicode))_. Este estándar asigna un número a virtualemente cada
carácter que alguna vez necesitarás, incluyendo caracteres del griego,
árabe, japonés, tamil, y otros alfabetos. Tener tales números es
útil para guardar las cadenas de texto dentro de la computadora porque
hace posible representarlas como una secuencia de números. Cuando
comparamos cadenas, JavaScript va de izquierda a derecha, comparando
los códigos numéricos de los caracteres uno por uno.
(((igualdad)))(((operador >=)))(((pass:[<=] operador)))(((operador
==)))(((operador != ))) Otros operadores similares son `>=` (mayor o
igual a), `<=` (menor o igual a), `==` (igual a), y `!=` (no es igual
a).
[source,javascript]
----
console.log("Itchy" != "Scratchy")
// → true
----
(((comparaciéon,de NaN)))(((NaN)))Sólo esxiste un valor en JavaScript
que no es igual a sí mismo, y este es `NaN`, que significa "no es un
número".
[source,javascript]
----
console.log(NaN == NaN)
// → false
----
La intención de `NaN` es representar el resultado de un cálculo sin
sentido y como tal, no es igual al resultado de cualquier _otro_
cálculo sin sentido.
=== Operadores Lógicos ===
(((razonamiento)))(((operadores lógicos)))Hay también algunas operaciones
que pueden ser aplicadas a los valores Booleanos. JavaScript soporta
tres operadores lógicos: _and_, _or_ y _not_. Estos pueden ser usados para
"razonar" con los Booleanos.
(((operador &&)))(((and lógico)))El operador `&&` representa la operación
lógica _and_ ("y"). Es un operador binario, y su resultado es verdadero(true)
sólo si los dos valores dados son verdaderos.
[source,javascript]
----
console.log(true && false)
// → false
console.log(true && true)
// → true
----
(((operador ||)))(((or lógico)))El operador `||` denota la operación
lógica _or_ ("o"). Devuelve verdadero si cualquiera de los dos valores
dados es verdadero.
[source,javascript]
----
console.log(false || true)
// → true
console.log(false || false)
// → false
----
(((negación)))(((operador !)))_Not_ (Negación) es escrito como un símbolo
de admiración (`!`). Es un operador binario que voltea el valor que se
le de; `!true` produce `false` y `!false` regresa `true`.
(((precedencia)))Cuando mezclamos estos operadores Booleanos con
aritmética y otros operadores, no es siempre obvio cuándo se necesitan los
paréntesis. En la prácitca, puedes avanzar sabiendo que de los operadores
que hemos visto hasta ahora, `||` tiene la menor precedencia, después
viene el `&&`, siguen los operadores de comparación(`>`, `==`, etc.),
y después los demás operadores. Este orden ha sido elegido tal que, en
expresiones típicas con la siguiente, sean necesarios tan pocos
paréntesis como sea posible:
[source,javascript]
----
1 + 1 == 2 && 10 * 10 > 50
----
(((ejecución condicional)))(((operador ternario)))(((operador ?:
)))(((operador condicional)))(((caracter dos puntos)))(((signo de
interrogación)))El último operador lógico del que hablaré no es unitario,
ni binario, sino _ternario_, opera en tres valores. Este es escrito con
un símbolo de interrogación y dos puntos, como sigue:
[source,javascript]
----
console.log(true ? 1 : 2);
// → 1
console.log(false ? 1 : 2);
// → 2
----
Este es llamado el operador _condicional_ (o algunas veces el operador
_tenario_ dado que es el único operador de este tipo en el lenguaje).
El valor a la izquierda del signo de interrogación "escoge" cuál de los
otros dos valores resultará. Cuando es verdadero, el valor central es
escogido, y cuando es falso, el valor de la derecha se da como resultado.
== Valores Indefinidos (Undefined) ==
(((undefined)))(((null)))(((indefinido)))Existen dos valores especiales,
escritos `null` y `undefined`, que son usados para denotar la ausencia
de un valor con significado. Son valores en sí mismos, pero no poseen
ninguna información.
Muchas operaciones en el lenguaje que no producen un valor con significado
(lo verás después) producen `undefined` simplemente porque tienen que producir
_algún_ valor.
La diferencia en el significado entre `undefined` y `null` es un accidente del
diseño de JavaScript, y no importa la mayoría del tiempo. En los casos en
dónde realmente te tienes que preocupar de estos valores, te recomiendo tratarlos
como intercambiables (más de esto en un momento).
== Conversión automática de tipos ==
(((NaN)))(((coerción de tipos)))En la introducción, mencioné que
JavaScript acepta casi cualquier programa que le des, incluso programas que
hagan cosas raras. Esto es muy bien demostrado por las siguientes expresiones:
[source,javascript]
----
console.log(8 * null)
// → 0
console.log("5" - 1)
// → 4
console.log("5" + 1)
// → 51
console.log("cinco" * 2)
// → NaN
console.log(false == 0)
// → true
----
(((operador +)))(((aritmética)))(((pass:[*] operador)))(((operador
-)))Cuando un operador es aplicado al tipo "incorrecto" de valor,
JavaScript convertirá silenciosamente el valor en el tipo de dato
que espera, usando un conjunto de reglas que a menudo no son lo que
tú quieres o esperas. Esto es llamado _((coerción de tipo))_. Así que
el `null` en la primera expresión se vuelve `0`, y el `"5"` en la
segunda expresión se convierte en `5` (de cadena a número). Aún así,
en la tercera expresión, `+` intenta hacer concatenación de cadenas
antes de suma numérica, así que el `1` es convertido en `"1"` (de
número a cadena).
(((coerción de tipo)))(((número,conversión a)))Cuando algo que no
se corresponde con un número de manera obvia (como `"cinco"` o
`undefined`) es convertido a un número, el valor resultante
es `NaN`. Las siguientes operaciones aritméticas sobre `NaN` seguirán
produciendo `NaN`, así que si te encuentras con uno de estos en
un lugar inesperado, busca conversiones accidentales de tipo.
(((null)))(((undefined)))(((comparación,de valores
indefinidos)))(((operador ==))) Cuando comparamos valores del mismo tipo
usando `==`, la salida es fácil de predecir: deberías obtener verdadero
cuando los dos valores sean el mismo, excepto en el caso de `NaN`.
Pero cuando los tipos son diferentes, JavaScript usa un complicado
y confuso conjunto de reglas para determinar qué hacer. En la mayoría
de los casos, sólo trata de convertir uno de los valores al tipo de
dato del otro valor. Sin embargo, cuando `null` o `undefined` están
en cualquier lado de la operación, resulta verdadero sólo en el caso
de que los dos lados sean `null` o `undefined`.
[source,javascript]
----
console.log(null == undefined);
// → true
console.log(null == 0);
// → false
----
Este último comportamiento es útil a menudo. Cuando quieres probar
si un valor tiene un significado real en vez de `null` o `undefined`,
simplemente comparas contra `null` con el operador `==` (o `!=`).
(((coerción de tipos)))(((Boolean,conversión a)))(((operador
===)))(((operador !==)))(((comparación)))¿Y si quieres probar
si algo se refiere precisamente al valor `false`? Las reglas para
convertir cadenas y números a Booleanos dicen que `0`, `NaN` y la
cadena vacía (`""`) cuentan como `false`, mientras que todos los
demás valores cuentan como `true`. Debido a esto, expresiones como
`0 == false` y `"" == false` también son verdaderas. Para casos como
este en el que _no_ quieres que ocurra ninguna conversión automática
de tipos, existen dos operadores extra: `===` y `!==`. El primero
prueba si un valor es precisamente igual a otro, y el segundo
si no es precisamente igual. Así que `"" === false` es falso como
se espera.
Yo recomiendo usar la comparación de tres caracteres defensivamente para
evitar que conversiones de tipos inesperadas te causen problemas. Pero
cuando estás seguro de que los tipos en ambos lados serán los mismos,
no hay problema con usar los operadores más cortos.
=== Corto circuito de operadores lógicos ===
(((coerciónd de tipos)))(((Booleanos,conversión a)))(((operador)))Los
operadores lógicos `&&` and `||` manejan los valores de diferentes
tipos de un modo peculiar. Convertirán el valor de su lado izquierdo
para decidir qué hacer, pero dependiendo del operador y del resultado
de la conversión, devuelven el valor del lado izquierdo _original_
o el del lado derecho.
(((operador ||)))El operador `||`, por ejemplo, regresará el valor de
la izquierda cuando pueda ser convertido a `true` y regresará el valor
a la derecha en cualquier otro caso. Esta conversión funciona como
esperarías con valores Booleanos y debería hacer algo análogo con
valores de otros tipos.
[source,javascript]
----
console.log(null || "user")
// → user
console.log("Karl" || "user")
// → Karl
----
(((valor por defecto)))Esta funcionalidad permite al operador `||`
ser usado como una manera de respaldarnos con un valor por defecto.
Si le das en el lado izquierdo una expresión que puede producir
un valor vacío, el valor de la derecha será usado como reemplazo
dado el caso.
(((operador &&)))El operador `&&` funciona de manera similar, pero
en sentido opuesto. Cuando el valor a su izquierda es algo que se
convierte en falso, regresa este valor, y en otro caso regresa el
valor de la derecha.
(((evaluación de corto circuito)))Otra importante propiedad de estos
dos operadores es que el lado derecho sólo es evaluado cuando es
necesario. En el caso de `true || X`, no importa lo que sea `X`,
incluso en si es una expresión que hace algo __terrible__, el resultado
será verdadero, y `X` no será evaluado nunca. Lo mismo ocurre para
`false && X`, lo cuál es falso e ignorará `X`. Esto es llamado
_evaluación de corto circuito_ (short-circuit evaluation).
(((operador ternario)))(((operador ?:)))(((operadores condicionales)))El
operador condicional trabaja de una forma similar. La primera expresión
es evaluada siempre, pero el segundo o tercer valor, el que no sea
escogido, no se evalúa.
== Resumen ==
Vimos cuatro tipos de valores de JavaScript en este capítulo: números,
cadenas, Booleanos, y valores indefinidos.
Estos valores son creados al escribir su nombre (`true`, `null`) o
valor (`13`, `"abc"`). Puedes combinar y transformar valores con los
operadores. Vimos operadores binarios para aritmética(`+`, `-`,
`*`, `/` y `%`), concatenación de cadenas (`+`), comparación
(`==`, `!=`, `===`, `!==`, `<`, `>`, `<=`, `>=`), y lógica
(`&&`, `||`), así como varios operadores unitarios (`-` para hacer
negativo un número, `!` para negar lógicamente y `typeof` para
obtener el tipo de un valor) y un operador ternario (`?:`) para
elegir entre dos valores basándonos en un tercero.
Esto te brinda suficiente información para usar JavaScript como una
pequeña calculadora, pero no para mucho más. El
link:02_program_structure.html#program_structure[siguiente capítulo]
empezará a entremezclar estas expresiones en programas básicos.