Ví dụ về toán tử bậc ba trong JavaScript với các hàm


91

Tôi đang sử dụng jQuery 1.7.1

Tôi mới bắt đầu sử dụng toán tử bậc ba của JavaScript để thay thế các câu lệnh if / else đơn giản. Tôi đã làm rất thành công ở một số nơi. Tôi đã rất ngạc nhiên khi tôi làm thành công một thứ khác hoạt động khi tôi nghĩ chắc chắn rằng nó sẽ không, nhưng dù sao thì tôi cũng đã thử.

Đây là tuyên bố ban đầu:

function updateItem() {
    $this = $(this);
    var IsChecked = $this.hasClass("IsChecked");
    if (IsChecked == true){
        removeItem($this);
    } else {
        addItem($this);
    }
}

Đây là cùng một hàm sử dụng toán tử bậc ba:

function updateItem() {
    $this = $(this);
    var IsChecked = $this.hasClass("IsChecked");
    (IsChecked == true) ? removeItem($this) : addItem($this);
}

Tôi rất ngạc nhiên vì tất cả các ví dụ tôi thấy đang được sử dụng chỉ đơn thuần là thiết lập các biến như thế này:

x = (1 < 2) ? true : false;

Câu hỏi của tôi là liệu đây có phải là cách sử dụng "bình thường" và nó sẽ hoạt động trong hầu hết các phiên bản JavaScript? Nó sẽ thất bại ở đâu? Có những công dụng khác ít rõ ràng hơn cho nó không?

CẬP NHẬT - Cảm ơn lời khuyên "thế giới thực" !!!

Tôi đang sử dụng cái này làm chức năng của mình:

function updateItem() {
    $this = $(this);
    $this.hasClass("IsChecked") ? removeItem($this) : addItem($this);
}

Nó là bình thường và nó sẽ hoạt động tốt .. Nói chung, khả năng đọc là khó khi sử dụng toán tử bậc ba nhưng trong trường hợp của bạn, nó có vẻ tốt.
Selvakumar Arumugam

1
Hmm .... bạn cũng có thể làm điều này vì cả hai đều chấp nhận các lý lẽ giống nhau (IsChecked ? removeItem : addItem)($this). Tuy nhiên, để trả lời câu hỏi của bạn, có, điều này là bình thường và không có gì sai khi sử dụng toán tử bậc ba miễn là chúng không làm giảm khả năng bảo trì hoặc khả năng đọc trong tình huống cần thiết. jsfiddle.net/vsB3f
Kevin B

if($this.hasClass("IsChecked")) removeItem($this); else addItem($this)là cách thích hợp. Các nhà điều hành ternary không có nghĩa là đối với trường hợp như thế này nhưng đối với những thứ như foo(isChecked ? 'bar' : meow());(tức là khi bạn quan tâm đến "giá trị trả về" của bất cứ điều gì bạn làm trong các khối sau đó / khác)
ThiefMaster

1
Trong ví dụ của bạn, hãy bỏ qua dòng đầu tiên có lợi cho điều này: $(this).hasClass("IsChecked") ? removeItem($this) : addItem($this); Tôi có thể hiểu mã của bạn nguyên trạng trên một dòng, vì vậy nó phù hợp với quy tắc ngón tay cái của tôi (xem bài đăng bên dưới). Làm việc cho tôi.
Những giấc mơ siêu thực vào

Câu trả lời:


189

Heh, có một số cách sử dụng cú pháp bậc ba khá thú vị trong câu hỏi của bạn; Tôi thích cái cuối cùng nhất ...

x = (1 < 2) ? true : false;

Việc sử dụng ternary ở đây là hoàn toàn không cần thiết - bạn có thể chỉ cần viết

x = (1 < 2);

Tương tự như vậy, phần tử điều kiện của câu lệnh bậc ba luôn được đánh giá là giá trị Boolean, do đó bạn có thể biểu thị:

(IsChecked == true) ? removeItem($this) : addItem($this);

Đơn giản như:

(IsChecked) ? removeItem($this) : addItem($this);

Trên thực tế, tôi cũng sẽ xóa IsCheckedtạm thời cũng như để lại cho bạn:

($this.hasClass("IsChecked")) ? removeItem($this) : addItem($this);

Đối với wether, đây là cú pháp có thể chấp nhận được, nó chắc chắn là như vậy! Đó là một cách tuyệt vời để giảm bốn dòng mã thành một mà không ảnh hưởng đến khả năng đọc. Lời khuyên duy nhất mà tôi dành cho bạn là tránh lồng nhiều câu lệnh bậc ba trên cùng một dòng (cách đó nói lên sự điên rồ!)


lưu ý rằng bạn có thể muốn tránh sử dụng chữ hoa trong tên lớp (IsChecked trở thành được kiểm tra) stackoverflow.com/questions/1547986/…
Adrien Be

JS có các hàm lớp đầu tiên:($this.hasClass("isChecked") ? removeItem : addItem)($this)
ClojureMostly là

22

Phong cách bậc ba thường được sử dụng để tiết kiệm không gian. Về mặt ngữ nghĩa, chúng giống hệt nhau. Tôi thích sử dụng cú pháp if / then / else đầy đủ hơn vì tôi không muốn hy sinh khả năng đọc - Tôi là người cũ và tôi thích niềng răng hơn.

Định dạng if / then / else đầy đủ được sử dụng cho hầu hết mọi thứ. Nó đặc biệt phổ biến nếu bạn tham gia vào các khối mã lớn hơn trong mỗi nhánh, bạn có một cây if / else phân nhánh hoặc nhiều else / ifs trong một chuỗi dài.

Toán tử bậc ba thường gặp khi bạn gán giá trị cho một biến dựa trên một điều kiện đơn giản hoặc bạn đang đưa ra nhiều quyết định với kết quả rất ngắn. Ví dụ mà bạn trích dẫn thực sự không có ý nghĩa, vì biểu thức sẽ đánh giá một trong hai giá trị mà không có bất kỳ logic bổ sung nào.

Ý kiến ​​hay:

this > that ? alert(this) : alert(that);  //nice and short, little loss of meaning

if(expression)  //longer blocks but organized and can be grasped by humans
{
    //35 lines of code here
}
else if (something_else)
{
    //40 more lines here
}
else if (another_one)  /etc, etc
{
    ...

Kém tốt:

this > that ? testFucntion() ? thirdFunction() ? imlost() : whathappuh() : lostinsyntax() : thisisprobablybrokennow() ? //I'm lost in my own (awful) example by now.
//Not complete... or for average humans to read.

if(this != that)  //Ternary would be done by now
{
    x = this;
}
else
}
    x = this + 2;
}

Một quy tắc ngón tay cái thực sự cơ bản - bạn có thể hiểu rõ toàn bộ sự việc hay tốt hơn trên một dòng không? Ternary là OK. Nếu không, hãy mở rộng nó.


7

Không có gì đặc biệt khó khăn về ví dụ bạn đã đăng.

Trong toán tử bậc ba, đối số đầu tiên (điều kiện) được đánh giá và nếu kết quả là true , đối số thứ hai được đánh giá và trả về, nếu không, đối số thứ ba được đánh giá và trả về. Mỗi đối số đó có thể là bất kỳ khối mã hợp lệ nào, bao gồm cả các lệnh gọi hàm.

Nghĩ theo cách này:

var x = (1 < 2) ? true : false;

Cũng có thể được viết là:

var x = (1 < 2) ? getTrueValue() : getFalseValue();

Điều này hoàn toàn hợp lệ và các hàm đó có thể chứa bất kỳ mã tùy ý nào, cho dù nó có liên quan đến việc trả về một giá trị hay không. Ngoài ra, kết quả của phép toán bậc ba không phải được gán cho bất kỳ thứ gì, cũng như kết quả của hàm không phải được gán cho bất kỳ thứ gì:

(1 < 2) ? getTrueValue() : getFalseValue();

Bây giờ chỉ cần thay thế chúng bằng bất kỳ chức năng tùy ý nào và bạn chỉ còn lại một cái gì đó giống như ví dụ của bạn:

(1 < 2) ? removeItem($this) : addItem($this);

Bây giờ, ví dụ cuối cùng của bạn thực sự không cần một con chim thứ ba, vì nó có thể được viết như thế này:

x = (1 < 2);  // x will be set to "true"

6

Nếu bạn định lồng các toán tử bậc ba, tôi tin rằng bạn muốn làm điều gì đó như sau:

   var audience = (countrycode == 'eu') ? 'audienceEU' :
                  (countrycode == 'jp') ? 'audienceJP' :
                  (countrycode == 'cn') ? 'audienceCN' :
                  'audienceUS';

Viết / đọc hiệu quả hơn rất nhiều so với:

var audience = 'audienceUS';
if countrycode == 'eu' {
   audience = 'audienceEU';
} else if countrycode == 'jp' {
   audience = 'audienceJP';
} else if countrycode == 'cn' {
   audience = 'audienceCN';
}

Như với tất cả các chương trình tốt, khoảng trắng làm cho mọi thứ trở nên tốt đẹp cho những người phải đọc mã của bạn sau khi bạn hoàn thành dự án.


6
Hoàn toàn không đồng ý với nhận xét ở trên của bạn về việc chim nhạn lồng nhau dễ đọc và gỡ lỗi hơn. Cá nhân, tôi muốn thấy khối else / if lồng nhau được thay thế bằng bảng tra cứu hoặc câu lệnh switch.
JonnyReeves

@JonnyReeves đồng ý - thường là cú pháp ternary lồng nhau được sử dụng tốt nhất khi kiểm tra điều kiện khác nhau (ví dụ modulo số )
AlexFoxGill

6

Tôi cũng muốn thêm một cái gì đó từ tôi.

Cú pháp có thể có khác để gọi các hàm với toán tử bậc ba, sẽ là:

(condition ? fn1 : fn2)();

Có thể hữu ích nếu bạn phải chuyển cùng một danh sách các tham số cho cả hai hàm, vì vậy bạn chỉ phải viết chúng một lần.

(condition ? fn1 : fn2)(arg1, arg2, arg3, arg4, arg5);

Bạn có thể sử dụng toán tử bậc ba ngay cả với các tên hàm thành viên, cá nhân tôi rất thích để tiết kiệm dung lượng:

$('.some-element')[showThisElement ? 'addClass' : 'removeClass']('visible');

hoặc là

$('.some-element')[(showThisElement ? 'add' : 'remove') + 'Class']('visible');

Một vi dụ khac:

var addToEnd = true; //or false
var list = [1,2,3,4];
list[addToEnd ? 'push' : 'unshift'](5);

2

Tôi biết câu hỏi đã được trả lời.

Nhưng hãy để tôi thêm một điểm ở đây. Đây không chỉ là trường hợp đúng hay sai. Xem bên dưới:

var val="Do";

Var c= (val == "Do" || val == "Done")
          ? 7
          : 0

Ở đây nếu val là Do hoặc Done thì c sẽ là 7, còn lại nó sẽ là 0. Trong trường hợp này c sẽ là 7.

Đây thực sự là một góc nhìn khác của nhà điều hành này.

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.