ตัวอย่าง JavaScript ternary operator พร้อมฟังก์ชัน


91

ฉันใช้ jQuery 1.7.1

ฉันเพิ่งเริ่มใช้ตัวดำเนินการ ternary JavaScript เพื่อแทนที่คำสั่ง if / else อย่างง่าย ฉันประสบความสำเร็จในหลาย ๆ ที่ ฉันรู้สึกประหลาดใจเมื่อฉันทำอย่างอื่นได้สำเร็จเมื่อฉันคิดว่ามันจะไม่สำเร็จ แต่ฉันก็พยายามต่อไป

นี่คือข้อความดั้งเดิม:

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

นี่คือฟังก์ชันเดียวกันโดยใช้ตัวดำเนินการ ternary:

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

ฉันรู้สึกประหลาดใจเพราะตัวอย่างทั้งหมดที่ฉันเห็นว่าใช้เป็นเพียงการตั้งค่าตัวแปรเช่นนี้:

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

คำถามของฉันคือการใช้งาน "ปกติ" หรือไม่และจะใช้ได้กับ JavaScript เกือบทุกเวอร์ชันหรือไม่ จะล้มเหลวไปถึงไหน มีการใช้งานอื่น ๆ ที่ชัดเจนน้อยกว่าหรือไม่?

UPDATE - ขอบคุณสำหรับคำแนะนำ "โลกแห่งความจริง" !!!

ฉันใช้สิ่งนี้เป็นหน้าที่ของฉัน:

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

เป็นเรื่องปกติและจะใช้งานได้ดี .. โดยทั่วไปแล้วการอ่านจะทำได้ยากเมื่อใช้ตัวดำเนินการที่เกี่ยวข้อง แต่ในกรณีของคุณมันดูดี
Selvakumar Arumugam

1
อืม .... (IsChecked ? removeItem : addItem)($this)คุณยังสามารถทำเช่นนี้ตั้งแต่พวกเขาทั้งสองยอมรับขัดแย้งกัน อย่างไรก็ตามเพื่อตอบคำถามของคุณใช่นี่เป็นเรื่องปกติและไม่มีอะไรผิดปกติในการใช้ตัวดำเนินการที่เกี่ยวข้องตราบใดที่พวกเขาไม่ได้ลดทอนความสามารถในการบำรุงรักษาหรือความสามารถในการอ่านในสถานการณ์ที่จำเป็น jsfiddle.net/vsB3f
Kevin B

if($this.hasClass("IsChecked")) removeItem($this); else addItem($this)เป็นวิธีที่เหมาะสม ตัวดำเนินการ ternary ไม่ได้มีไว้สำหรับกรณีเช่นนี้ แต่สำหรับสิ่งต่างๆเช่นfoo(isChecked ? 'bar' : meow());(เช่นเมื่อคุณสนใจเกี่ยวกับ "ค่าส่งคืน" ของสิ่งที่คุณทำในช่วงนั้น / else)
ThiefMaster

1
ในตัวอย่างของคุณให้ข้ามบรรทัดแรกไปในทำนองนี้: $(this).hasClass("IsChecked") ? removeItem($this) : addItem($this); ฉันเข้าใจโค้ดของคุณได้เหมือนเดิมในบรรทัดเดียวดังนั้นจึงเหมาะกับหลักการทั่วไปของฉัน (ดูโพสต์ด้านล่าง) เหมาะสำหรับฉัน
Surreal Dreams

คำตอบ:


189

เดี๋ยวก่อนมีการใช้ไวยากรณ์ที่น่าตื่นเต้นในคำถามของคุณ ชอบอันสุดท้ายที่สุด ...

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

การใช้ ternary ที่นี่ไม่จำเป็นโดยสิ้นเชิงคุณสามารถเขียนได้

x = (1 < 2);

ในทำนองเดียวกันองค์ประกอบเงื่อนไขของคำสั่ง ternary จะถูกประเมินเป็นค่าบูลีนเสมอดังนั้นคุณจึงสามารถแสดง:

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

เช่นเดียวกับ:

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

ในความเป็นจริงฉันจะลบIsCheckedชั่วคราวด้วยเช่นกันซึ่งทำให้คุณ:

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

สำหรับว่านี่เป็นไวยากรณ์ที่ยอมรับได้แน่นอน! เป็นวิธีที่ยอดเยี่ยมในการลดโค้ดสี่บรรทัดให้เป็นหนึ่งเดียวโดยไม่ส่งผลต่อความสามารถในการอ่าน คำแนะนำเพียงคำเดียวที่ฉันจะให้คุณคือหลีกเลี่ยงการซ้อนคำสั่งซ้อนท้ายหลาย ๆ คำในบรรทัดเดียวกัน (วิธีนี้เป็นการบ้าคลั่ง!)


โปรดทราบว่าคุณอาจต้องการหลีกเลี่ยงการใช้ตัวพิมพ์ใหญ่ในชื่อคลาส (IsChecked become is-checked) stackoverflow.com/questions/1547986/…
Adrien Be

JS มีฟังก์ชันระดับเฟิร์สคลาส:($this.hasClass("isChecked") ? removeItem : addItem)($this)
Clojure มากที่สุดใน

22

โดยทั่วไปจะใช้สไตล์ ternary เพื่อประหยัดพื้นที่ มีความหมายเหมือนกัน ฉันชอบใช้ไวยากรณ์ if / then / else แบบเต็มเพราะฉันไม่ชอบเสียสละความสามารถในการอ่าน - ฉันเป็นโรงเรียนเก่าและฉันชอบจัดฟัน

รูปแบบ if / then / else แบบเต็มใช้สำหรับทุกอย่าง เป็นที่นิยมโดยเฉพาะอย่างยิ่งหากคุณเข้าสู่บล็อกโค้ดที่มีขนาดใหญ่ขึ้นในแต่ละสาขาคุณมีต้นไม้ if / else แบบแยกส่วนหรือหลาย ๆ อัน / ifs ในสตริงแบบยาว

ตัวดำเนินการ ternary เป็นเรื่องปกติเมื่อคุณกำหนดค่าให้กับตัวแปรตามเงื่อนไขง่ายๆหรือคุณกำลังทำการตัดสินใจหลายอย่างพร้อมผลลัพธ์สั้น ๆ ตัวอย่างที่คุณอ้างถึงไม่สมเหตุสมผลเพราะนิพจน์จะประเมินเป็นค่าใดค่าหนึ่งจากสองค่าโดยไม่มีตรรกะเพิ่มเติม

ข้อคิดดีๆ:

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
{
    ...

ดีน้อย:

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

พื้นฐานจริงๆกฎของหัวแม่มือ - คุณสามารถเข้าใจสิ่งที่ทั้งเป็นดีหรือดีกว่าในบรรทัดเดียว? Ternary ก็โอเค มิฉะนั้นให้ขยาย


7

ไม่มีอะไรยุ่งยากเป็นพิเศษเกี่ยวกับตัวอย่างที่คุณโพสต์

ในตัวดำเนินการ ternary อาร์กิวเมนต์แรก (เงื่อนไข) จะได้รับการประเมินและถ้าผลลัพธ์คือtrueอาร์กิวเมนต์ที่สองจะถูกประเมินและส่งคืนมิฉะนั้นอาร์กิวเมนต์ที่สามจะถูกประเมินและส่งคืน อาร์กิวเมนต์แต่ละรายการสามารถเป็นบล็อกรหัสที่ถูกต้องรวมถึงการเรียกใช้ฟังก์ชัน

คิดแบบนี้:

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

สามารถเขียนเป็น:

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

สิ่งนี้ใช้ได้อย่างสมบูรณ์และฟังก์ชันเหล่านั้นอาจมีรหัสใด ๆ ก็ได้ไม่ว่าจะเกี่ยวข้องกับการส่งคืนค่าหรือไม่ก็ตาม นอกจากนี้ผลลัพธ์ของการดำเนินการ ternary ไม่จำเป็นต้องกำหนดให้กับสิ่งใดเลยเช่นเดียวกับที่ผลลัพธ์ของฟังก์ชันไม่จำเป็นต้องถูกกำหนดให้กับสิ่งใด:

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

ตอนนี้เพียงแค่แทนที่ฟังก์ชันเหล่านั้นด้วยฟังก์ชันใด ๆ โดยพลการและคุณจะเหลือบางอย่างเช่นตัวอย่างของคุณ:

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

ตอนนี้ตัวอย่างสุดท้ายของคุณไม่จำเป็นต้องมี ternary เลยเนื่องจากสามารถเขียนได้ดังนี้:

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

7

ฉันต้องการเพิ่มบางอย่างจากฉันด้วย

ไวยากรณ์อื่น ๆ ที่เป็นไปได้ในการเรียกใช้ฟังก์ชันด้วยตัวดำเนินการ ternary จะเป็น:

(condition ? fn1 : fn2)();

อาจเป็นประโยชน์หากคุณต้องส่งรายการพารามิเตอร์เดียวกันไปยังทั้งสองฟังก์ชันดังนั้นคุณต้องเขียนเพียงครั้งเดียว

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

คุณสามารถใช้ตัวดำเนินการ ternary ได้แม้จะมีชื่อฟังก์ชันสมาชิกซึ่งโดยส่วนตัวแล้วฉันชอบมากเพื่อประหยัดพื้นที่:

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

หรือ

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

ตัวอย่างอื่น:

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

6

หากคุณกำลังจะซ้อนตัวดำเนินการ ternary ฉันเชื่อว่าคุณต้องการทำสิ่งนี้:

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

การเขียน / อ่านมีประสิทธิภาพมากกว่า:

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

เช่นเดียวกับการเขียนโปรแกรมที่ดีช่องว่างทำให้ทุกอย่างดีสำหรับผู้ที่ต้องอ่านโค้ดของคุณหลังจากเสร็จสิ้นโครงการ


6
ไม่เห็นด้วยอย่างยิ่งกับความคิดเห็นข้างต้นของคุณเกี่ยวกับการซ้อนทับที่ง่ายต่อการอ่านและแก้ไขข้อบกพร่อง โดยส่วนตัวแล้วฉันอยากจะเห็นบล็อกอื่นที่ซ้อนกัน / ถ้าแทนที่ด้วยตารางการค้นหาหรือคำสั่งสวิตช์
JonnyReeves

@JonnyReeves เห็นด้วย - โดยปกติแล้วไวยากรณ์ของ ternary ที่ซ้อนกันจะใช้ได้ดีที่สุดเมื่อตรวจสอบเงื่อนไขต่างๆ (เช่นโมดูโลของตัวเลข )
AlexFoxGill

2

ฉันรู้ว่าคำถามมีคำตอบอยู่แล้ว

แต่ขอผมเพิ่มหนึ่งจุดตรงนี้ นี่ไม่ใช่กรณีของจริงหรือเท็จเท่านั้น ดูด้านล่าง:

var val="Do";

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

ที่นี่ถ้า val คือ Do หรือ Done ดังนั้น c จะเป็น 7 มิฉะนั้นจะเป็นศูนย์ ในกรณีนี้ c จะเป็น 7

นี่เป็นอีกมุมมองหนึ่งของตัวดำเนินการนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.