2011-12-20 14 views
8

¿Por qué javascript prefiere devolver un String sobre cualquier otra opción?return String vs Integer vs undefined vs null

Considere el siguiente fragmento.

var arr = ['Hello1', 'Hello2', 'Hello3']; 

Array.prototype.item = function(x) { 
    return this[x] || null || 'aïe' || 12 || undefined ; 
}; 

console.log(arr.item(43)); // returns aïe 

I llamados intencionalmente un elemento de matriz inexistente.

Sin embargo, no puedo entender por qué arr.item(43) devuelve el String? ¿Por qué no null o undefined o incluso 12?

Respuesta

25

Porque this[x] es undefined, que es falso, al igual que null.

El operador || devuelve el primer valor de "veracidad" que encuentra, y detiene su evaluación en ese punto.

Si no se encuentra un valor "verdadero", devuelve el resultado del último operando evaluado.

Hay un total de 6 valores "falsey". Son ...

  1. false
  2. undefined
  3. null
  4. ""
  5. NaN
  6. 0

Todo más se considera verdad.

Así que su expresión se evaluará como ...

// v--falsey   v--truthy! return it! 
((((this[x] || null) || 'aïe') || 12) || undefined); 
//    ^--falsey   ^--------^---these are not evaluated at all 

O usted podría mirarlo de esta manera:

(
    (
    (
     (this[x] || null) // return null 
      /* (null */ || 'aïe') // return 'aïe' and stop evaluating 
           || 12) 
             || undefined); 
+1

¡Salud! Perfectamente claro :) – Pierre

+2

Solo un pequeño detalle, el '||' devuelve la última expresión evaluada. En cuyo caso, cuando uno es * truthy *, devolverá eso. – alex

+0

@alex: Hmmm ... sí, pero la primera expresión "verídico" * es * la última evaluada. Tal vez no hice hincapié en el cortocircuito de manera explícita. Voy a actualizar. –

1

La cadena es el primer valor Truthy en la cadena de o de. Simples.

1

Porque está evaluando en orden de izquierda a derecha.

Si se va a modificar a esto:

return this[x] || null || 12 || 'aïe' || undefined ; 

Su respuesta sería 12.

3

El código a || b es más o menos equivalente a a ? a : b, o el código un poco más detallado:

if (a) { 
    result = a; 
} else { 
    result = b; 
} 

Dado que || es left-associative, la expresión a || b || c se evalúa como (a || b) || c.


Así que en términos simples, esto significa que el operador || cuando encadenó devuelve el primer operando que es "Truthy", o de lo contrario el último elemento.

Esta característica puede ser útil para proporcionar valores por defecto cuando se tiene valores perdidos:

var result = f() || g() || defaultValue; 

se puede leer esto como: obtener el resultado de f(). Si es un valor falsey, entonces prueba g(). Si eso también le da un valor de falsey, entonces use defaultValue.

5

La declaración

return this[x] || null || 'aïe' || 12 || undefined ; 

evaluará las subexpresiones de izquierda a derecha, y volverá la primera subexpresión que no se evalúa como falsa . El elemento inexistente se evalúa como falso ya que no está definido, y null es falso por definición. Eso deja a la cadena como la primera subexpresión no , así que eso es lo que obtienes.

0

return this[x] || null || 'aïe' || 12 || undefined no devolverá uno de esos. Se supone que devuelve el resultado de la expresión this[x] || null || 'aïe' || 12 || undefined - Creo que devolverá un valor booleano.