Niềng răng có cần thiết trong câu lệnh một dòng trong JavaScript không?


161

Tôi đã từng nghe nói rằng việc để các dấu ngoặc nhọn trong các câu lệnh một dòng có thể gây hại trong JavaScript. Tôi không nhớ lý do nữa và một tìm kiếm Google không giúp được gì nhiều.

Có bất cứ điều gì làm cho nó là một ý tưởng tốt để bao quanh tất cả các câu lệnh trong dấu ngoặc nhọn trong JavaScript không?

Tôi đang hỏi, bởi vì mọi người dường như làm như vậy.


5
Lưu ý: chỉ có câu lệnh đầu tiên là giả sử phạm vi, ngay cả khi bạn có một vài câu lệnh trên một dòng, vì vậy đó không phải là "câu lệnh một dòng" mà là câu lệnh đơn
Kris Ivanov

1
Bạn có thể nghĩ về vấn đề được mô tả trong câu trả lời này
Blorgbeard sẽ ra vào

@Blorgbeard: không, tôi thực sự đã trả lời câu trả lời đó trong khi trước đây.
Tháp

Hah, vậy tôi thấy. Đừng bận tâm sau đó :)
Blorgbeard sẽ ra vào

Đây là câu trả lời của bạn: Medium.com/@jonathanabrams/
Erwan Legrand

Câu trả lời:


203

Không

Nhưng họ được khuyến khích. Nếu bạn mở rộng tuyên bố, bạn sẽ cần chúng.

Điều này là hoàn toàn hợp lệ

if (cond) 
    alert("Condition met!")
else
    alert("Condition not met!")

Tuy nhiên, rất khuyến khích bạn luôn luôn sử dụng niềng răng vì nếu bạn (hoặc ai đó) mở rộng câu lệnh thì sẽ được yêu cầu.

Thực hành tương tự này theo sau trong tất cả các ngôn ngữ kiểu cú pháp C với giằng. C, C ++, Java, thậm chí PHP đều hỗ trợ câu lệnh một dòng mà không cần dấu ngoặc. Bạn phải nhận ra rằng bạn chỉ lưu hai ký tự và với một số kiểu giằng của một số người, bạn thậm chí không lưu một dòng. Tôi thích một kiểu nẹp đầy đủ (như sau) vì vậy nó có xu hướng dài hơn một chút. Sự đánh đổi được đáp ứng rất tốt với thực tế là bạn có khả năng đọc mã cực kỳ rõ ràng.

if (cond) 
{
    alert("Condition met!")
}
else
{
    alert("Condition not met!")
}

28
+1, câu trả lời thông tin. Cá nhân tôi chưa bao giờ thấy hữu ích khi làm điều "được đề xuất" này. Tôi chưa bao giờ mã hóa trăn, vì vậy tôi không chỉ chèn mọi thứ và mong đợi vết lõm có vấn đề. Nếu tôi thêm một tuyên bố, tôi cũng thêm niềng răng. Luôn luôn. Không thể nhớ một lần nó cắn tôi. Không phải trong C, không phải trong C # không phải trong JavaScript.
Jakob

16
@Kirk: Douglas Crockford khuyên bạn nên điều đó. Tôi đồng ý rằng đó là một quyết định cá nhân chủ quan nhưng khi làm việc trong một nhóm sẽ dễ dàng hơn để gõ niềng răng.
Josh K

10
@Josh, oh, Crockford đã nói điều đó. Đó phải là từ cuối cùng. ;) (chỉ đùa thôi) Vấn đề là tính chủ quan của điểm này trải rộng trên tất cả các ngôn ngữ giống như C, và ý kiến ​​mạnh mẽ có thể được tìm thấy trong suốt (cho cả hai vị trí).
Kirk Woll

11
Kinh nghiệm cá nhân của tôi cho thấy rằng việc không đặt các khẩu trang có thể dẫn đến những rắc rối lớn khi làm việc theo nhóm.
Thưa ông

4
Đó là một thực hành tốt để luôn luôn sử dụng niềng răng {}. Như @Arx đã nói, sẽ có nhiều lỗi hơn nếu bạn bỏ chúng. Apple thậm chí đã có một lỗi trong SSL / TLS của iOS vì họ không sử dụng niềng răng
Keenan Lidral-Porter

94

Có một khía cạnh dễ đọc - trong đó khi bạn có các câu lệnh ghép, nó có thể trở nên rất khó hiểu. Việc thụt lề giúp nhưng không có ý nghĩa gì với trình biên dịch / trình thông dịch.

var a;
var b;
var c;

//Indenting is clear
if (a===true)
  alert(a); //Only on IF
alert(b); //Always

//Indenting is bad
if (a===true)
  alert(a); //Only on IF
  alert(b); //Always but expected?

//Nested indenting is clear
if (a===true)
  if (b===true)
    alert(a); //Only on if-if
alert (b); //Always

//Nested indenting is misleading
if (a===true)
  if (b===true)
    alert(a); //Only on if-if
  alert (b); //Always but expected as part of first if?

//Compound line is misleading
//b will always alert, but suggests it's part of if
if (a===true) alert(a);alert(b); 
else alert(c); //Error, else isn't attached

Và sau đó là một khía cạnh mở rộng:

//Problematic
if (a===true)
  alert(a);
  alert(b); //We're assuming this will happen with the if but it'll happen always
else       //This else is not connected to an if anymore - error
  alert(c);

//Obvious
if (a===true) {
  alert(a); //on if
  alert(b); //on if
} else {
  alert(c); //on !if
} 

Suy nghĩ rằng nếu bạn luôn có dấu ngoặc thì bạn biết chèn các câu lệnh khác vào trong khối đó.


4
Đó là lý do tại sao chúng ta nên luôn luôn sử dụng nó như một lớp lót : if (a===true) alert(a);. Bây giờ thì rõ rồi!
João Pimentel Ferreira

1
Sử dụng xoăn-trái-ngoặc và xoăn-phải-ngoặc làm cho các điều kiện rõ ràng. Đối với những người mơ mộng trong chúng ta, cũng được gọi là chim bay trái và phải.
HalfMens

61

Câu hỏi hỏi về các tuyên bố trên một dòng. Tuy nhiên, nhiều ví dụ được cung cấp cho thấy lý do không bỏ qua niềng răng dựa trên nhiều câu lệnh. Hoàn toàn an toàn khi không sử dụng dấu ngoặc trên một dòng, nếu đó là kiểu mã hóa bạn thích.

Ví dụ, câu hỏi hỏi liệu điều này có ổn không:

 if (condition) statement;

Nó không hỏi nếu điều này là ok:

 if (condition)
   statement;

Tôi nghĩ rằng bỏ dấu ngoặc ra là thích hợp hơn vì nó làm cho mã dễ đọc hơn với cú pháp ít thừa hơn.

Phong cách mã hóa của tôi là không bao giờ sử dụng dấu ngoặc trừ khi mã là một khối. Và không bao giờ sử dụng nhiều câu lệnh trên một dòng (cách nhau bằng dấu chấm phẩy). Tôi thấy điều này dễ đọc và rõ ràng và không bao giờ có vấn đề về phạm vi 'nếu'. Kết quả là, sử dụng dấu ngoặc trên một câu lệnh if điều kiện sẽ yêu cầu 3 dòng. Như thế này:

 if (condition) {
   statement;
 }

Sử dụng một dòng nếu câu lệnh là thích hợp hơn vì nó sử dụng ít không gian dọc hơn và mã nhỏ gọn hơn.

Tôi sẽ không ép buộc người khác sử dụng phương pháp này, nhưng nó hiệu quả với tôi và tôi không thể không đồng ý nhiều hơn với các ví dụ được cung cấp về cách bỏ dấu ngoặc dẫn đến lỗi mã hóa / phạm vi.


1
Tôi luôn cảm thấy một người nên luôn luôn bao gồm cả niềng răng ... nhưng tôi đang suy nghĩ lại về nó bây giờ. Bạn có hướng dẫn phong cách airbnb về phía bạn!
gửi

1
Tuy nhiên, bạn quên rằng hầu hết các trình định dạng mã thay đổi thành định dạng 2 dòng và bạn quay lại mã có vấn đề. Đối số không gian dọc chỉ là ngớ ngẩn. Khả năng đọc luôn luôn chiến thắng, và màn hình ngày nay là rất lớn.
Kim

1
2 dòng được thêm cho mỗi khung, để bao quanh các câu lệnh một dòng của bạn không phải là một chi phí lớn so với thiệt hại tiềm tàng có thể gây ra bởi một - nhà phát triển thậm chí rất cẩn thận - duy trì mã của bạn. Bản thân bạn có thể là một nhà phát triển tuyệt vời với các kỹ năng thần thoại, nhưng bạn không thể cho rằng đồng nghiệp của mình là như vậy. HÔN, bọc mọi thứ với một bối cảnh và làm cho nó dễ dàng nhất có thể cho người khác hoặc cuối cùng bạn sẽ gặp rắc rối.
Maciej Tokarz

@senderle Quy tắc eslint để kiểm soát điều này có thể được tìm thấy ở đây: eslint.org/docs/rules/curly#multi /*eslint curly: ["error", "multi"]*/
Silkfire

15

Về mặt kỹ thuật thì không nhưng hoàn toàn khác Có !!!

Hãy quên đi "Đó là sở thích cá nhân", "mã sẽ chạy tốt", "nó đã hoạt động tốt với tôi", "nó dễ đọc hơn" yada yada BS. Điều này có thể dễ dàng dẫn đến những vấn đề rất nghiêm trọng nếu bạn mắc lỗi và tin tôi rằng rất dễ mắc lỗi khi bạn đang viết mã (Đừng tin?, Hãy xem Apple nổi tiếng gặp lỗi ).

Luận điểm: "Đó là sở thích cá nhân"

Không có nó không phải là. Trừ khi bạn là một đội một người đàn ông rời đi trên sao hỏa, không. Hầu hết thời gian sẽ có người khác đọc / sửa đổi mã của bạn. Trong bất kỳ nhóm mã hóa nghiêm túc nào, đây sẽ là cách được đề xuất, vì vậy đó không phải là 'sở thích cá nhân'.

Đối số: "mã sẽ chạy tốt"

Mã spaghetti cũng vậy! Có nghĩa là nó ổn để tạo ra nó?

Luận điểm: "nó đã hoạt động tốt với tôi"

Trong sự nghiệp của tôi, tôi đã thấy rất nhiều lỗi được tạo ra vì vấn đề này. Bạn có thể không nhớ bao nhiêu lần bạn nhận xét 'DoSomething()'và bối rối tại sao 'SomethingElse()'được gọi là:

if (condition) 
    DoSomething();
SomethingElse();

Hoặc đã thêm 'SomethingMore' và không nhận thấy nó sẽ không được gọi (mặc dù vết lõm có nghĩa khác):

if (condition)
  DoSomething();
  SomethingMore();

Đây là một ví dụ thực tế mà tôi đã có. Ai đó muốn bật tất cả các bản ghi để họ chạy find & thay thế "console.log"=> //"console.log":

if (condition) 
   console.log("something");
SomethingElse();

Thấy vấn đề?

Ngay cả khi bạn nghĩ, "những thứ này quá tầm thường, tôi sẽ không bao giờ làm điều đó"; hãy nhớ rằng sẽ luôn có một thành viên trong nhóm có kỹ năng lập trình kém hơn bạn (hy vọng bạn không phải là người kém nhất trong nhóm!)

Luận điểm: "nó dễ đọc hơn"

Nếu tôi đã học được bất cứ điều gì về lập trình, thì đó là những điều đơn giản trở nên rất phức tạp rất nhanh. Điều này rất phổ biến rằng:

if (condition) 
    DoSomething();

biến thành như sau sau khi nó đã được thử nghiệm với các trình duyệt / môi trường / trường hợp sử dụng khác nhau hoặc các tính năng mới được thêm vào:

if (a != null)
   if (condition) 
      DoSomething();
   else
      DoSomethingElse(); 
      DoSomethingMore();
else 
    if (b == null)
         alert("error b");
    else 
         alert("error a");

Và so sánh nó với điều này:

 if (a != null) {
    if (condition) { 
       DoSomething();
    }
    else {
       DoSomethingElse();
       DoSomethingMore();
    }
 } else if (b == null) {
    alert("error b");
 } else {
    alert("error a");
 }

PS: Điểm thưởng thuộc về người nhận thấy lỗi trong ví dụ trên.


2
cũng là lỗi rõ ràng là DoS SomethingMore (); Nhưng cũng có một lỗi khác. nếu a là null và b là null, bạn chỉ nhận được "lỗi b", bạn không bao giờ nhận được "lỗi a".
rocketsarefast

Theo ví dụ của bạn, nhóm phát triển của bạn không biết cách viết mã, niềng răng sẽ không giúp họ ...
Carlos ABS

một số ví dụ là từ nhóm nhà phát triển của Apple
Caner

13

Không có vấn đề bảo trì!

Vấn đề với tất cả các bạn là bạn đặt dấu chấm phẩy ở mọi nơi. Bạn không cần niềng răng xoăn cho nhiều câu lệnh. Nếu bạn muốn thêm một câu lệnh, chỉ cần sử dụng dấu phẩy.

if (a > 1)
 alert("foo"),
 alert("bar"),
 alert("lorem"),
 alert("ipsum");
else
 alert("blah");

Đây là mã hợp lệ sẽ chạy như bạn mong đợi!


2
Bạn không có nghĩa là if, elsealertkhông If, ElseAlert?
Anish Gupta

Ồ, tôi không biết điều này, cảm ơn bạn đã thông báo cho tôi! Có vẻ như hầu hết mọi người bỏ qua chi tiết quan trọng này.
Hendeca

13
Mặc dù điều này hoạt động với JavaScript, nhưng nó vượt xa tôi tại sao bạn muốn làm điều đó. Tôi mạo hiểm đoán rằng phần lớn các nhà phát triển không nhận thức được điều này (bản thân tôi đã bao gồm trước khi đọc nó), điều mà tôi nghi ngờ sau đó sẽ nhanh chóng trở thành vấn đề bảo trì giữa các nhà phát triển. Đôi khi, cách thông minh nhất không phải là tốt nhất.
Simon

14
Điều này thật kinh khủng. Nếu ai đó thêm một câu lệnh và quên biến dấu chấm phẩy thành dấu phẩy ở câu thứ hai đến câu lệnh cuối cùng trong khối, bạn có một lỗi rất khó phát hiện vì dấu phẩy và dấu chấm phẩy ở cuối dòng trông cũng vậy giống.
Ingo Bürk

1
Tôi thích cách tiếp cận "Hemingwayian" : rất sạch sẽ. Và không có khoảng trống giữa if(, giống nhưif(true) doSomething();
victorf 17/08/2015

8

Không có lý do lập trình để sử dụng dấu ngoặc nhọn trên các câu lệnh một dòng.

Điều này chỉ đến với sở thích và khả năng đọc của lập trình viên.

Mã của bạn sẽ không bị hỏng vì nó.


7

Ngoài lý do được đề cập bởi @Josh K (cũng áp dụng cho Java, C, v.v.), một vấn đề đặc biệt trong JavaScript là chèn dấu chấm phẩy tự động . Từ ví dụ Wikipedia:

return
a + b;

// Returns undefined. Treated as:
//   return;
//   a + b;

Vì vậy, điều này cũng có thể mang lại kết quả bất ngờ, nếu được sử dụng như thế này:

if (x)
   return
   a + b;

Nó không thực sự tốt hơn để viết

if (x) {
   return
   a + b;
}

nhưng có lẽ ở đây lỗi dễ phát hiện hơn một chút (?)


Tất cả những ví dụ đó trông thật kinh khủng đối với tôi, trừ khi các nhà văn là tạm thời và được trả tiền theo dòng hoặc cho đến khi nó hoạt động.
Cees Timmerman

6

Đó là một vấn đề về phong cách, nhưng niềng răng xoăn là tốt để ngăn chặn nguy hiểm có thể khác .


4

Có rất nhiều câu trả lời hay, vì vậy tôi sẽ không lặp lại, ngoại trừ việc nói quy tắc của tôi, khi niềng răng có thể được bỏ qua: với điều kiện 'quay trở lại' hoặc 'ném' (ví dụ) như là tuyên bố duy nhất của họ . Trong trường hợp này, kiểm soát luồng đã rõ ràng rằng nó chấm dứt:

Ngay cả trường hợp xấu cũng có thể được xác định nhanh chóng (và cố định) do điều khiển luồng kết thúc. Khái niệm / cấu trúc quy tắc này cũng áp dụng cho một số ngôn ngữ.

if (x)
    return y;
    always();

Tất nhiên, đây cũng là lý do tại sao người ta có thể sử dụng một kẻ nói dối ..


3

Đây là lý do tại sao nó được đề nghị

Hãy nói tôi viết

if(someVal)
    alert("True");

Sau đó, nhà phát triển tiếp theo đến và nói "Ồ, tôi cần phải làm gì khác", vì vậy họ viết

if(someVal)
    alert("True");
    alert("AlsoTrue");

Bây giờ, như bạn có thể thấy "Ngoài ra" sẽ luôn đúng, bởi vì nhà phát triển đầu tiên đã không sử dụng niềng răng.


Điều đó không chính xác, bạn đang thiếu thông báo 'other': if (someVal) ("True"); cảnh báo khác ("Ngoài ra"); sẽ đúng Tôi sẽ không sử dụng nó vì tôi thích {} vì nó dễ đọc hơn nhiều.
Gerrit B

1
Huh? Tôi đã không có một tuyên bố khác. Tôi đã nói rằng nếu không có dấu ngoặc nhọn, nó có thể dẫn đến lỗi nếu ai đó thêm một dòng mới. Tôi nghĩ bạn đã không hiểu quan điểm của tôi.
Amir Raminfar

Tôi nghĩ những gì anh ấy nói là, dòng thứ 2 sẽ được thực hiện bất kể điều gì. Một câu lệnh If không có dấu ngoặc chỉ có thể thực thi 1 dòng.
PostCodeism

3

Tôi hiện đang làm việc trên một công cụ khai thác. Ngay cả bây giờ tôi kiểm tra nó trên hai kịch bản lớn. Thực nghiệm tôi phát hiện ra: Bạn có thể loại bỏ các dấu ngoặc nhọn phía sau cho, nếu, khác, trong khi, chức năng * nếu các dấu ngoặc nhọn không bao gồm ';', 'return', 'for', 'if', 'other', 'trong khi', 'làm', 'chức năng'. Không phân biệt ngắt dòng.

function a(b){if(c){d}else{e}} //ok  
function a(b){if(c)d;else e}   //ok

Tất nhiên bạn cần thay thế nẹp đóng bằng dấu chấm phẩy nếu nó không theo sau trên nẹp đóng khác.

Hàm không được kết thúc bằng dấu phẩy.

var a,b=function()c;  //ok *but not in Chrome
var b=function()c,a;  //error  

Đã thử nghiệm trên Chrome và FF.


2

Luôn luôn thấy rằng

if(valid) return;

trong mắt tôi dễ hơn

if(valid) {
  return;
}

cũng có điều kiện như

(valid) ? ifTrue() : ifFalse();

dễ đọc hơn (ý kiến ​​cá nhân của tôi) hơn là

if(valid) {
  ifTrue();
} else {
  ifFalse();
}

nhưng tôi đoán nó đi xuống theo phong cách mã hóa


2

Không trả lời trực tiếp câu hỏi, nhưng dưới đây là một cú pháp ngắn về điều kiện nếu trên một dòng

Ví dụ:

var i=true;
if(i){
  dosomething();
}

Có thể được viết như thế này:

var i=true;
i && dosomething();


1

Tôi tìm thấy câu trả lời này tìm kiếm về một trải nghiệm tương tự vì vậy tôi quyết định trả lời nó với kinh nghiệm của tôi.

Báo cáo không có khung làm việc trong hầu hết các trình duyệt, tuy nhiên, tôi đã thử nghiệm rằng các phương thức không có khung trong thực tế không hoạt động trong một số trình duyệt.

Kể từ ngày 26 tháng 2 năm 2018, tuyên bố này hoạt động trong Pale Moon, nhưng không phải Google Chrome.

function foo()
   return bar;

0

Mức thụt đầu dòng của một câu lệnh phải bằng với số dấu ngoặc mở phía trên nó. (không bao gồm dấu ngoặc kép được trích dẫn hoặc nhận xét hoặc chỉ định trong chỉ thị tiền xử lý)

Nếu không, K & R sẽ là phong cách thụt lề tốt. Để khắc phục kiểu của chúng, tôi khuyên bạn nên đặt các câu lệnh if đơn giản trên một dòng.

if (foo) bar();    // I like this. It's also consistent with Python FWIW

thay vì

if (foo)
   bar();   // not so good

Nếu tôi đang viết một trình soạn thảo, tôi sẽ làm cho nút định dạng tự động của nó hút thanh ngang hàng với foo và tôi sẽ làm cho nó chèn dấu ngoặc quanh thanh nếu bạn nhấn return trước khi nó như thế này:

if (foo) {
  bar();    // better
}

Sau đó, thật dễ dàng và nhất quán để thêm các câu lệnh mới bên trên hoặc bên dưới thanh bên trong phần thân của câu lệnh if

if (foo) {
  bar();    // consistent
  baz();    // easy to read and maintain
}

-1

Đôi khi chúng dường như là cần thiết! Tôi không thể tin vào bản thân mình, nhưng hôm qua nó đã xảy ra với tôi trong một phiên Firebird (Firefox 22.0 gần đây)

if (! my.condition.key)
    do something;

thực hiện làm một cái gì đó mặc dù my.condition.keyđúng . Thêm niềng răng:

if (! my.condition.var) {
    do something;
}

Đã sửa vấn đề đó. Có rất nhiều ví dụ về việc nó dường như hoạt động mà không cần niềng răng, nhưng trong trường hợp này chắc chắn là không.

Tất nhiên, những người có xu hướng đặt nhiều hơn một tuyên bố trên một dòng nên chắc chắn luôn luôn sử dụng niềng răng, bởi vì những thứ như

if (condition)
    do something; do something else;

rất khó tìm.


Tôi tò mò về kịch bản nào việc thiếu niềng răng đã khiến điều kiện if trở thành sự thật, bạn có thể nhớ lại hoặc đưa ra một ví dụ thực tế về nó không?
gitsitgo

Biểu thức điều kiện luôn được đánh giá trước câu lệnh. Tôi cũng rất tò mò muốn xem một ví dụ thực tế về điều này bởi vì nó sẽ đại diện cho một lỗi trong trình thông dịch.
Dấu chấm phẩy

-1

Tôi chỉ muốn lưu ý rằng bạn cũng có thể loại bỏ các dấu ngoặc nhọn của người khác. Như đã thấy trong bài viết này của John Resig .

if(2 == 1){
    if(1 == 2){
        console.log("We will never get here")
    }
} else 
    console.log("We will get here")

[Kiểu niềng răng Qt] [1] yêu cầu các khối ở cả hai mặt của elsekhớp để sử dụng niềng răng - ví dụ này sẽ yêu cầu niềng răng trên elsekhối để vượt qua đánh giá mã. [1]: wiki.qt.io/Qt_Coding_Style#Braces
pixelgreas

Tại sao các downvote? Các tuyên bố trên là chính xác 100%.
Johnston

-1

Có một cách để đạt được nhiều dòng niềng răng không cong nếu câu lệnh .. (Wow tiếng anh ..) nhưng thật là tẻ nhạt:

if(true)
   funcName();
else
   return null;


function funcName(){
  //Do Stuff Here...
}

Bạn không cần phải có quá nhiều dòng mới khi bỏ qua các dấu ngoặc nhọn. Trên đây cũng có thể được viết trên hai dòng là: if (true) funcName()else return null
phobos
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.