Mengapa hasil bervariasi berdasarkan penempatan kurung kurawal?

119

Mengapa cuplikan kode di bawah, yang diambil dari artikel ini , memberikan hasil yang berbeda karena hanya satu perubahan dalam penempatan kurung kurawal?

Ketika kurung kurawal buka {pada baris baru, test()kembali undefined, dan "tidak - putus: tidak ditentukan" ditampilkan dalam peringatan.

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);
}

Ketika kurung kurawal berada di baris yang sama dengan return, test()mengembalikan objek, dan "fantastis" diperingatkan.

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);
}

Baru belajar
sumber
semantik semi-penyisipan setelahnya returnsedikit berbeda daripada di tempat lain, dan pemutusan baris "lebih berarti" di tempat itu daripada "di tengah".
dandavis

Jawaban:

165

Itulah salah satu perangkap JavaScript: penyisipan titik koma otomatis. Garis yang tidak diakhiri dengan titik koma, tetapi bisa menjadi akhir dari pernyataan, secara otomatis dihentikan, jadi contoh pertama Anda terlihat seperti ini:

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

Lihat juga panduan gaya JS Douglas Crockford , yang menyebutkan penyisipan titik koma.

Dalam contoh kedua Anda, Anda mengembalikan sebuah objek (dibangun oleh tanda kurung kurawal) dengan properti javascriptdan nilainya "fantastic", efektif sama seperti ini:

function test() {
    var myObject = new Object();
    myObject.javascript = "fantastic";
    return myObject;
}
Residuum
sumber
5
Fakta Menarik: Pada beberapa mesin Anda dapat mengomentari titik koma yang dimasukkan secara otomatis
Christopher Tarquini
1
@ ChrisT: Apa? Yang mana Apakah ini dieksplorasi di mana saja?
Sean McMillan
1
@SeanMcMillan Saya benar-benar telah membaca artikel tentangnya tetapi sepertinya saya tidak dapat menemukan satu pun dari mereka dari pencarian cepat. Saya ingat bahwa menempatkan return /*dan kemudian */{ akan secara efektif mengomentari titik koma yang tersembunyi di versi chrome yang lebih lama. Tidak yakin apakah itu masih berlaku
Christopher Tarquini
2
Karena keunikan ini, saya berjanji pada diri sendiri 10 tahun lalu: menjauhlah dari web! Saya berdoa semoga Interwebs menghilang ... Sayangnya itu tidak berjalan sesuai rencana, dan sekarang saya harus berjuang dengan masalah ini juga. Karma adalah ab * tch :)
Jowen
1
Saya telah melihat orang-orang yang secara religius menentang titik koma di JavaScript, saya selalu bertanya-tanya apa yang mereka lakukan dengan waktu ekstra yang mereka hemat dengan tidak menempatkan titik koma.
Iman Mohamadi
9

Javascript tidak memerlukan titik koma di akhir pernyataan, tetapi kekurangannya adalah ia harus menebak di mana letak titik koma. Sering kali hal ini bukan masalah, tetapi terkadang hal ini menciptakan titik koma yang tidak Anda inginkan.

Contoh dari posting blog saya tentang ini ( Javascript - hampir tidak berbasis garis ):

Jika Anda memformat kode seperti ini:

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

Maka diartikan seperti ini:

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

Pernyataan return mengambil bentuk tanpa parameternya, dan argumennya menjadi pernyataannya sendiri.

Hal yang sama terjadi pada kode Anda. Fungsi tersebut diartikan sebagai:

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

Saya pribadi lebih suka Gaya Allman untuk keterbacaan (vs gaya K&R).

Dari pada…

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

Saya suka…

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

  return obj;
}

Tapi ini solusi. Aku bisa menerimanya.

Michael R
sumber
3
Saya pikir kita harus menghindari preferensi pribadi yang menyimpang dari arus utama. Kita harus mengikuti pilihan mayoritas, yang mendorong konsistensi, yang akan meningkatkan keterbacaan
Jowen
1
Saya menemukan kodenya lebih mudah dibaca daripada K&R. Cukup subjektif jika maksud Anda "dapat dibaca"
Bran
Saya lebih suka Allman juga ... tetapi karena ASI, ketika saya perlu mengembalikan objek, saya meninggalkan semi pada baris yang sama dengan pengembalian. Saya lebih suka ini daripada menambahkan satu baris "var x =" ...
Mik
1

Itu karena javascript paling sering menempatkan ";" di akhir setiap baris, jadi pada dasarnya ketika Anda memiliki kembali {di baris yang sama, mesin javascript melihat bahwa akan ada sesuatu yang lebih, dan ketika di baris baru ia berpikir Anda lupa untuk meletakkan ";", dan menaruhnya untuk Anda.

cichy
sumber
1
Saya tidak mengerti mengapa jawaban cichy, Darwin, dan Ivo diturunkan suara?
BoltClock
1

Tanda kurung kurawal di sini menunjukkan konstruksi objek baru. Jadi kode Anda sama dengan:

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

yang berfungsi sedangkan jika Anda menulis:

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

itu tidak lagi berfungsi.

Darin Dimitrov
sumber
0

Masalahnya memang injeksi titik koma seperti dijelaskan di atas. Saya baru saja membaca posting blog yang bagus tentang hal ini. Ini menjelaskan masalah ini dan lebih banyak lagi tentang javascript. Ini juga berisi beberapa referensi yang bagus. Anda bisa membacanya di sini

Ivo van der Wijk
sumber
Ya, saya juga membacanya, setelah membaca saya meminta di sini untuk menjelaskan lebih baik oleh dalang js.
JustLearn