Các toán tử Ternary trong JavaScript mà không có Else khác


149

Tôi luôn phải đặt nulltrong những điều kiện khác mà không có gì cả. Có dù sao xung quanh nó? Ví dụ

condition ? x = true : null;

về cơ bản, có một cách để làm:

condition ? x = true;

Bây giờ nó hiển thị như là một lỗi cú pháp

FYI, đây là một số mã ví dụ thực tế:

!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null;

21
sử dụng một ternary như condition ? x = true : null;có lẽ nên được viết là x = (condition ? true : null);. Bên cạnh đó, trong javascript nullđánh giá là sai vì vậy trong trường hợp NÀY, bạn có thể x = (condition);và đạt được kết quả tương tự.
Matt S

1
matt, câu trả lời của bạn là tốt nhất, nhưng nó không phải là một câu trả lời, đó là một nhận xét!
Cheeso

Matt, mã THỰC TẾ của tôi là :! Mặc định.sl trìnhWidth? defaults.sl lanhWidth = obj.find ('img'). width () + 'px': null; một cách ngắn hơn, tốt hơn để viết đó?
Oscar Godson

2
defaults.slemonyWidth = defaults.slemonyWidth || obj.find ('img'). width () + 'px';
kennebec

sẽ tốt hơn để tránh việc gán danh tính, vì vậy đây chỉ là một điều kiện:if (!defaults.slideshowWidth) defaults.slideshowWidth = obj.find('img').width()+'px'
Mihail Malostanidis

Câu trả lời:


225

Trước hết, một biểu thức ternary không phải là sự thay thế cho cấu trúc if / other - nó tương đương với cấu trúc if / other trả về một giá trị. Nghĩa là, một mệnh đề if / other là mã, một biểu thức ternary là một biểu thức , có nghĩa là nó trả về một giá trị.

Điều này có nghĩa là một số điều:

  • chỉ sử dụng các biểu thức ternary khi bạn có một biến ở bên trái =nghĩa là được gán giá trị trả về
  • chỉ sử dụng biểu thức ternary khi giá trị được trả về là một trong hai giá trị (hoặc sử dụng biểu thức lồng nhau nếu phù hợp)
  • mỗi phần của biểu thức (sau? và sau :) sẽ trả về một giá trị không có tác dụng phụ (biểu thức x = truetrả về true vì tất cả các biểu thức trả về giá trị cuối cùng, nhưng cũng thay đổi x mà không có bất kỳ ảnh hưởng nào đến giá trị được trả về)

Nói tóm lại - việc sử dụng 'chính xác' của một biểu thức ternary là

var resultofexpression = conditionasboolean ? truepart: falsepart;

Thay vì ví dụ của bạn condition ? x=true : null ;, nơi bạn sử dụng biểu thức ternary để đặt giá trị củax , bạn có thể sử dụng biểu thức này:

 condition && (x = true);

Đây vẫn là một biểu thức và do đó có thể không vượt qua xác nhận, vì vậy một cách tiếp cận thậm chí tốt hơn sẽ là

 void(condition && x = true);

Cái cuối cùng sẽ vượt qua xác nhận.

Nhưng một lần nữa, nếu giá trị mong đợi là boolean, chỉ cần sử dụng kết quả của chính biểu thức điều kiện

var x = (condition); // var x = (foo == "bar");

CẬP NHẬT Liên quan đến mẫu của bạn, điều này có lẽ phù hợp hơn:

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

4
SO tuyệt vời, không cho phép chỉnh sửa để sửa i/elselỗi chính tả vì nó không đủ ký tự.
sương

1
void (condition && x = true) - điều này có vẻ tuyệt vời nhưng dường như gây ra lỗi "gán bên trái không hợp lệ"
Eugene Tiurin

1
void (condition && (x = true)) // giữ cho phép gán tách biệt với giá trị đầu tiên
diamondsea

4
Tuy nhiên, điều này không trực quan để đọc, đặc biệt đối với các nhà phát triển không quen với phong cách này. Bạn có thể viết nó dễ dàng và dễ đọc hơn như sau: if (condition) {x = true; }
diamondsea

2
Bạn có thể giải thích ý của bạn là "có thể không vượt qua xác nhận" không? Tôi không hiểu tại sao người ta nên gói biểu thức vào void(). cảm ơn.
gilad mayani

20

Không, nó cần ba toán hạng. Đó là lý do tại sao chúng được gọi là ternary nhà khai thác .

Tuy nhiên, với những gì bạn có làm ví dụ, bạn có thể làm điều này:

if(condition) x = true;

Mặc dù an toàn hơn khi niềng răng nếu bạn cần thêm nhiều hơn một tuyên bố trong tương lai:

if(condition) { x = true; }

Chỉnh sửa: Bây giờ bạn đề cập đến mã thực tế mà câu hỏi của bạn áp dụng cho:

if(!defaults.slideshowWidth)
    { defaults.slideshowWidth = obj.find('img').width()+'px'; }

1
Bạn có thể, nhưng bạn không nên. Atleast không phải không có dấu ngoặc nhọn xung quanh nó - nó rất có lỗi.
Konerak

1
điều đó có đúng không Tôi hiểu lý do chính để yêu cầu curlies là vì chúng làm cho cuộc sống của jslint dễ dàng hơn.
Cheeso

@Cheeso nó bị lỗi theo nghĩa tái cấu trúc. YOu quay lại để thêm nhiều việc phải làm trong trường hợp điều kiện thực sự mà không nhận ra rằng không có dấu ngoặc nhọn ở đó. Mã mới sẽ luôn luôn thực thi thay vì trường hợp khi đúng.
Matt S

Không tôi biết, tôi chỉ thích viết các điều kiện không có phần bổ sung, chẳng hạn như if () {} khác {} khi nó bằng đơn giản?:;
Oscar Godson

3
Thành thật mà nói, tôi chưa bao giờ biết các nhà phát triển sợ sử dụng ngôn ngữ hơn Javascript: -PI sẽ không thích ai đó nói với tôi rằng tôi không nên sử dụng dấu ngoặc nhọn. Tôi bỏ qua chúng rất nhiều và không bao giờ gặp rắc rối nào hơn là tôi vô tình thiếu một chiếc nẹp.
Andy E

12

Mọi người thường sử dụng các toán tử logic để rút ngắn cú pháp câu lệnh:

!defaults.slideshowWidth &&
  (defaults.slideshowWidth = obj.find('img').width()+'px');

Nhưng trong trường hợp cụ thể của bạn, cú pháp có thể đơn giản hơn nữa

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

Mã này sẽ trả về defaults.slideshowWidthgiá trị nếu defaults.slideshowWidthđược đánh giá là đúng vàobj.find('img').width()+'px' giá trị khác.

Xem phần Đánh giá ngắn mạch của các toán tử logic để biết chi tiết.


11
var x = condition || null;

2
(defaults.slideshowWidth) || (defaults.slideshowWidth = obj.find('img').width()+'px')hoặcdefaults.slideshowWidth = defaults.slideshowWidth || (obj.find('img').width()+'px')
Casey Chu

> Trả về expr1 nếu nó có thể được chuyển đổi thành true; mặt khác, trả về expr2. Toán tử logic (MDN)
Szabolcs Páll

5

Bạn có thể viết

x = condition ? true : x;

Vì vậy, x là không thay đổi khi điều kiện là sai.

Điều này sau đó tương đương với

if (condition) x = true

BIÊN TẬP:

!defaults.slideshowWidth 
      ? defaults.slideshowWidth = obj.find('img').width()+'px' 
      : null 

Có một vài lựa chọn thay thế - tôi không nói rằng những thứ này tốt hơn / tệ hơn - chỉ đơn thuần là những lựa chọn thay thế

Truyền vào null là tham số thứ ba hoạt động vì giá trị hiện tại là null. Nếu bạn tái cấu trúc và thay đổi điều kiện, thì có một mối nguy hiểm là điều này không còn đúng nữa. Vượt qua giá trị hiện tại là lựa chọn thứ 2 trong đội bảo vệ chim nhạn chống lại điều này:

!defaults.slideshowWidth = 
      ? defaults.slideshowWidth = obj.find('img').width()+'px' 
      : defaults.slideshowwidth 

An toàn hơn, nhưng có lẽ không đẹp khi nhìn vào, và gõ nhiều hơn. Trong thực tế, tôi có thể viết

defaults.slideshowWidth = defaults.slideshowWidth 
               || obj.find('img').width()+'px'

Một số mã trực tiếp là (dù sao để loại bỏ null trong này?) :! Defaults.sl lanhWidth? defaults.sl lanhWidth = obj.find ('img'). width () + 'px': null;
Oscar Godson

2

Trong trường hợp của bạn, tôi thấy toán tử ternary là dự phòng. Bạn có thể gán biến trực tiếp cho biểu thức, sử dụng toán tử ||, &&.

!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null ;

sẽ trở thành :

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

Rõ ràng hơn, đó là phong cách "javascript" hơn.


2

Đơn giản là gì

    if (condition) { code if condition = true };

1

Để sử dụng Toán tử Ternary mà không cần khai báo mảng hoặc đối tượng khác, bạn có thể sử dụng toán tử trải ES6 ...()

const cond = false;
const arr = [
  ...(cond ? ['a'] : []),
  'b',
];
    // ['b']

Và đối với các đối tượng:

const cond = false;
const obj = {
  ...(cond ? {a: 1} : {}),
  b: 2,
};
    // {b: 2}

nguồn chính thức

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.