Perché i risultati variano in base al posizionamento del tutore riccio?


119

Perché gli snippet di codice riportati di seguito, presi da questo articolo , producono risultati diversi a causa di un solo cambiamento nel posizionamento delle parentesi graffe?

Quando la parentesi graffa di apertura si {trova su una nuova riga, test()restituisce undefinede "no - si è rotto: undefined" viene visualizzato nell'avviso.

function test()
{
  return
  { /* <--- curly brace on new line */
    javascript: "fantastic"
  };
}

var r = test();
try {
  alert(r.javascript); // does this work...?
} catch (e) {
  alert('no - it broke: ' + typeof r);
}

Quando la parentesi graffa si trova sulla stessa riga di return, test()restituisce un oggetto e "fantastico" viene avvisato.

function test()
{
  return { /* <---- curly brace on same line */
    javascript: "fantastic"
  };
}

var r = test();
try {
  alert(r.javascript); // does this work...?
} catch (e) {
  alert('no - it broke: ' + typeof r);
}


la semantica di semi-inserimento dopo returnè leggermente diversa rispetto ad altri punti, e un'interruzione di riga "significa più" in quel punto di quanto non sarebbe "midstream".
dandavis

Risposte:


165

Questa è una delle insidie ​​di JavaScript: l'inserimento automatico del punto e virgola. Le righe che non terminano con un punto e virgola, ma potrebbero essere la fine di un'istruzione, vengono terminate automaticamente, quindi il tuo primo esempio è effettivamente simile a questo:

function test()
{
  return; // <- notice the inserted semicolon
  { 
    javascript: "fantastic"
  };
}

Vedi anche la guida di stile JS di Douglas Crockford , che menziona l'inserimento del punto e virgola.

Nel tuo secondo esempio restituisci un oggetto (costruito dalle parentesi graffe) con la proprietà javascripte il suo valore di "fantastic", effettivamente lo stesso di questo:

function test() {
    var myObject = new Object();
    myObject.javascript = "fantastic";
    return myObject;
}

5
Curiosità: su alcuni motori è possibile commentare i punti
Christopher Tarquini

1
@ ChrisT: cosa? Quale? È esplorato da qualche parte?
Sean McMillan

1
@SeanMcMillan Ho sicuramente letto articoli a riguardo ma non riesco a trovarne nessuno da una rapida ricerca. Ricordo che mettere return /*e poi */{ commenterebbe efficacemente il punto e virgola nascosto nelle versioni precedenti di Chrome. Non sono sicuro che sia ancora valido
Christopher Tarquini

2
A causa di queste stranezze ho fatto una promessa a me stesso 10 anni fa: stai lontano dal web! Ho pregato che gli Interweb svanissero ... Sfortunatamente non è andato come previsto, e ora devo lottare anche con questi problemi. Il karma è
stupido

1
Ho visto persone religiosamente contrarie al punto e virgola in JavaScript, mi sono sempre chiesto che cosa fanno con quel tempo extra che risparmiano non mettendo i punti e virgola.
Iman Mohamadi

9

Javascript non richiede il punto e virgola alla fine delle istruzioni, ma lo svantaggio è che deve indovinare dove sono i punti e virgola. Il più delle volte questo non è un problema, ma a volte inventa un punto e virgola dove non ne avevi l'intenzione.

Un esempio dal mio post sul blog su questo ( Javascript - quasi non basato sulla riga ):

Se formatti il ​​codice in questo modo:

function getAnswer() {
   var answer = 42;
   return
      answer;
}

Quindi viene interpretato in questo modo:

function getAnswer() {
  var answer = 42;
  return;
  answer;
}

L'istruzione return assume la sua forma senza parametri e l'argomento diventa un'istruzione a sé stante.

Lo stesso accade al tuo codice. La funzione viene interpretata come:

function test()
{
  return;
  {
    javascript : "fantastic"
  };
}

3

Personalmente preferisco lo stile Allman per la leggibilità (rispetto allo stile K&R).

Invece di…

function test() {
  return {
    javascript : "fantastic"
  };
}

Mi piace…

function test() 
{
  var obj =
  {
    javascript : "fantastic"
  };

  return obj;
}

Ma questa è una soluzione. Però posso conviverci.


3
Penso che dovremmo evitare preferenze personali che deviano dal mainstream. Dovremmo seguire le scelte della maggioranza, che promuove la coerenza, che aumenterà la leggibilità
Jowen

1
Trovo il suo codice più leggibile del K&R. Piuttosto soggettivo quando intendi "leggibile"
Bran

Anch'io preferisco l'Allman ... ma per via dell'ASI, quando devo restituire un oggetto, lascio il semi sulla stessa linea del reso. Preferisco questo piuttosto che aggiungere una riga "var x =" ...
Mik

1

È perché javascript molto spesso inserisce ";" alla fine di ogni riga, quindi fondamentalmente quando hai return {nella stessa riga, il motore javascript vede che ci sarà qualcosa di più, e quando è in una nuova riga pensa che ti sei dimenticato di mettere ";", e lo mette per te.


1
Non capisco perché le risposte di Cichy, Darin e Ivo siano state sottovalutate?
BoltClock

1

Le parentesi graffe qui indicano la costruzione di un nuovo oggetto. Quindi il tuo codice è equivalente a:

function test() {
  var a = { javascript : "fantastic" };
  return a;
}

che funziona mentre se scrivi:

function test() {
  var a = { javascript : "fantastic" };
  return; // ; is automatically inserted 
      a;
}

non funziona più.


0

Il problema è in effetti l'iniezione di punto e virgola come descritto sopra. Ho appena letto un bel post sul blog su questo argomento. Spiega questo problema e molto altro su javascript. Contiene anche alcuni buoni riferimenti. Puoi leggerlo qui


Sì, l'ho letto anche io, dopo aver letto chiedo qui di spiegarmi meglio da mastermind di js.
JustLearn
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.