2012-02-08 34 views
5

Một trong những người bạn của tôi đang dạy một lớp lập trình với Javascript và một trong những bài tập của anh ấy là tạo ra một trò chơi đoán số. Đây là ví dụ về việc triển khai ví dụ:Từ khóa ngắt trong Javascript chỉ có nghĩa là vi phạm các vòng lặp?

funProgram: for(;;) { 
    numberGuesser: { 
    var num = (Math.random() * 100) | 0; 
    var guess = +prompt("I'm thinking of a number between 0 and 100. Try to guess it.", 0); 
    var guesses = 1; 
    guess: for(;;) { 
     higher: { 
     lower: { 
      if(guess === num) break guess; 
      if(guess > num) break lower; 
      guess = +prompt("Too low. Try again.", 0); 
      break higher; 
     } 
     guess = +prompt("Too high. Try again.", 0); 
     } 
     guesses++; 
    } 
    alert("You got it in " + guesses + " guesses! The number is " + num); 
    } 
    var again = prompt("Do you want to guess again (y/n)?", "y") === "y"; 
    if(!again) break funProgram; 
} 

Ông ấy nói với tôi rằng thực tiễn tốt là gắn nhãn mã của bạn và bao quanh dễ dàng. Anh ta cũng nói rằng những sự phá vỡ được ghi nhãn và tiếp tục dễ đọc hơn nhiều so với những người không dán nhãn bởi vì bạn có thể biết chính xác những gì bạn đang phá vỡ. Tôi chưa bao giờ thấy bất kỳ mẫu mã như thế này, vì vậy tôi không chắc chắn nếu điều này là đúng sự thật.

Tôi đã sử dụng Javascript một thời gian và có một vài điều ở đây mà tôi chưa bao giờ thấy trước đây và một số điều mà tôi vẫn chưa hiểu. Tôi nghĩ rằng từ khóa break đặc biệt có nghĩa là để thoát ra khỏi vòng lặp. Các khối higherlower không phải là vòng lặp, nhưng dường như bạn vẫn có thể thoát ra khỏi nó. Làm thế nào là có thể? Nó có vẻ kỳ lạ với tôi để thoát ra khỏi cái gì đó không lặp lại. Bạn cũng có thể thoát ra khỏi các chức năng bằng cách sử dụng từ khóa break không?

Trả lời

3

Breaks can in fact have labels (và chấp nhận chúng). Tuy nhiên, tôi không chắc ai là "anh ta", nhưng tôi sẽ đi xa như để nói "Anh ta" đang truyền đạt lý tưởng của mình về lập trình, chứ không phải là một tiêu chuẩn cụ thể. Đó là để nói, không cần phải sử dụng nhãn, nó chỉ làm cho nó dễ đọc hơn cho người cụ thể đó. (Và, IMHO, nhãn là gợi nhớ của BASIC/GOTO ngày thường kết quả trong Spaghetti Code).

Tín dụng bổ sung: Hỏi bạn của bạn xem họ đã từng viết BASIC chưa; Tôi cá là bạn sẽ nhận được "có" (cùng với nhiều thói quen xấu trong suốt thời gian của khóa học - đó không phải là hồ sơ, tôi chưa bao giờ có trải nghiệm tốt với các lập trình viên BASIC/VB sau [hiện tại ] Các mẫu mã hóa))

Lệnh break thường được sử dụng để thoát khỏi vòng lặp, tuy nhiên nếu khối mã được lồng trong nhãn, bạn đang thiết lập một khối khác mà bạn có thể ngắt. Nó cũng mang đến cho bạn sự linh hoạt hơn một chút về việc nơi nghỉ có nghĩa là để thoát khỏi. Ví dụ:

for (;;){ // "for a" 
    for(;;){ // "for b" 
    break; // breaks "for b" 
    } 
} 

Trong trường hợp này, break chỉ nhằm thoát khỏi vòng lặp lồng nhau ("cho b"). Tuy nhiên:

myblock: { 
    for(;;){ 
    for(;;){ 
     break mybock; // breaks label "myblock" 
    } 
    } 
} 

Trong trường hợp này, ngắt thực sự thoát cả hai vòng vì bạn đang hướng dẫn nó thoát khỏi toàn bộ khối nhãn.Điều này sẽ gần giống như có:

function myblock(){ 
    for(;;){ 
    for(;;){ 
     return; // exits function "myblock" 
    } 
    } 
} 

Trường hợp return thoát khối tương tự như cách break myblock hoạt động.


Bằng cách này, không phải vì không có gì, tôi tìm thấy điều này một chút dễ dàng hơn để đọc:

var again = true; 
while (again){ 
    var num = (new Date()).getMilliseconds() % 100, 
     guess = +prompt("I'm thinking of a number between 0 and 100. Try to guess it.", "1"), 
     guesses = 1; 
    while (num !== guess){ 
     guesses++; 
     guess = +prompt((guess < num ? "Too low." : "Too high.") + " Try again.", guess); 
    } 
    alert("You got it in " + guesses + " guesses! The number is " + num); 
    again = prompt("Do you want to guess again? (y/n)", "y") == "y"; 
} 
+0

+1. Tôi sẽ là người ở hàng rào đối diện ... "Anh ta". Tôi muốn nói ghi nhãn tất cả các ngắt "chuẩn" sẽ làm cho mã * ít * dễ đọc hơn, vì thiếu "sử dụng hàng ngày" của nhãn làm cho nó nổi bật là "điều này khác với tiêu chuẩn' break' ", có nghĩa là tôi ' sẽ dành thời gian để đảm bảo rằng 'ngắt' này, thực sự, hoạt động chính xác như nó sẽ không có nhãn. – JimmiTh

0

From MDN (mỏ đậm nhấn mạnh):

Tuyên bố break bao gồm một nhãn tùy chọn cho phép các chương trình để thoát ra khỏi một tuyên bố nhãn. Tuyên bố break cần phải là được lồng trong tuyên bố được gắn nhãn này. Tuyên bố được gắn nhãn có thể là bất kỳ tuyên bố nào block; nó không phải được bắt đầu bằng một câu lệnh vòng lặp .

Vì vậy, có, nhãn có thể được sử dụng ngoài vòng lặp, nhưng, không, bạn không thể sử dụng chúng để trả về từ một hàm.

0

Những break báo cáo đang được sử dụng trong cùng một cách mà goto được sử dụng trong ngôn ngữ trở lên. Và như Shark chỉ ra: bạn cũng có thể sử dụng chúng trong báo cáo chuyển đổi, nhưng không phải trong các chức năng.

Điều này có thể gây nhầm lẫn cho bạn bởi vì anh ấy đang sử dụng các khối được gắn nhãn kết hợp với vòng lặp vô hạn for(;;).

Nhìn vào bài viết này vào đây để biết thêm thông tin: http://james.padolsey.com/javascript/labelled-blocks-useful/

1

tôi có thể hiểu đoạn code sau một nghiên cứu nhỏ trên labelbreak trong javascript. Tuy nhiên, cá nhân tôi không thích kiểu mã hóa đó, chủ yếu là vì cú pháp được gắn nhãn block quá giống với ký hiệu đối tượng theo nghĩa đen - mà tôi sử dụng nhiều. Và thậm chí tài liệu của Mozilla về nhãn cho chúng tôi biết để tránh chúng:

Nhãn không thường được sử dụng trong JavaScript vì chúng làm cho chương trình khó đọc hơn. Càng nhiều càng tốt, tránh sử dụng các nhãn và, tùy thuộc vào các trường hợp, thích các chức năng gọi điện thoại hoặc ném một lỗi.

Về câu hỏi mục tiêu của bạn:

  1. break thể được sử dụng để thoát for vòng, while vòng và case báo cáo, cũng như dán nhãn blocks.

  2. Bạn không thể sử dụng break để thoát chức năng, bạn phải sử dụng return.

Các vấn đề liên quan