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.