ผู้ประกอบการที่สามใน JavaScript โดยไม่ต้อง "อื่น"


149

ฉันมักจะต้องใส่nullในเงื่อนไขอื่นที่ไม่มีอะไรเลย มีอยู่รอบ ๆ มันไหม? เช่น

condition ? x = true : null;

โดยพื้นฐานแล้วมีวิธีทำอย่างไร:

condition ? x = true;

ตอนนี้มันปรากฏขึ้นเป็นข้อผิดพลาดทางไวยากรณ์

FYI นี่คือตัวอย่างโค้ดจริงบางส่วน:

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

21
ใช้ประกอบไปด้วยเช่นอาจจะต้องเขียนเป็นcondition ? x = true : null; x = (condition ? true : null);นอกจากนี้ในจาวาสคริปต์nullจะประเมินผลเป็นเท็จดังนั้นในกรณีนี้คุณสามารถทำได้x = (condition);และได้ผลลัพธ์เดียวกัน
Matt S

1
แมตต์คำตอบของคุณดีที่สุด แต่มันไม่ใช่คำตอบมันเป็นความคิดเห็น!
Cheeso

แมตต์รหัสจริงของฉันคือ:! defaults.slideshowWidth? defaults.slideshowWidth = obj.find ('img'). width () + 'px': null; วิธีที่สั้นกว่าและดีกว่าในการเขียน
ออสการ์ Godson

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

มันจะเป็นการดีกว่าที่จะหลีกเลี่ยงการระบุตัวตนดังนั้นนี่ควรเป็นเงื่อนไข:if (!defaults.slideshowWidth) defaults.slideshowWidth = obj.find('img').width()+'px'
Mihail Malostanidis

คำตอบ:


226

ก่อนอื่นนิพจน์ประกอบไปด้วยการแทนที่ไม่ใช่สำหรับการสร้าง if / else มันเทียบเท่ากับการสร้าง if / else ที่ส่งคืนค่า นั่นคือประโยค if / else คือรหัสนิพจน์ประกอบไปด้วยคือนิพจน์ซึ่งหมายความว่าจะส่งคืนค่า

นี่หมายถึงหลายสิ่ง:

  • ใช้นิพจน์ประกอบไปด้วยก็ต่อเมื่อคุณมีตัวแปรทางด้านซ้ายของค่า=นั้นเพื่อกำหนดค่าส่งคืน
  • ใช้นิพจน์ประกอบไปด้วยก็ต่อเมื่อค่าที่ส่งคืนเป็นหนึ่งในสองค่า (หรือใช้นิพจน์ที่ซ้อนกันหากเหมาะสม)
  • เป็นส่วนหนึ่งของการแสดงออก (หลังและหลัง?) แต่ละคนควรกลับค่าไม่มีผลข้างเคียง (การแสดงออกx = trueผลตอบแทนที่แท้จริงเป็นนิพจน์ทั้งหมดกลับค่าที่ผ่านมา แต่ยังมีการเปลี่ยนแปลงโดยไม่ต้อง x x มีผลกระทบใด ๆ กับค่าส่งกลับ)

ในระยะสั้น - การใช้ 'ถูกต้อง' ของนิพจน์ประกอบไปด้วยคือ

var resultofexpression = conditionasboolean ? truepart: falsepart;

แทนที่จะเป็นตัวอย่างของคุณcondition ? x=true : null ;ซึ่งคุณใช้นิพจน์ประกอบไปด้วยเพื่อตั้งค่าxคุณสามารถใช้สิ่งนี้:

 condition && (x = true);

นี่ยังคงเป็นนิพจน์และอาจไม่ผ่านการตรวจสอบดังนั้นวิธีการที่ดียิ่งขึ้นก็คือ

 void(condition && x = true);

อันสุดท้ายจะผ่านการตรวจสอบ

แต่จากนั้นอีกครั้งหากค่าที่คาดหวังคือบูลีนให้ใช้ผลลัพธ์ของนิพจน์เงื่อนไขในตัวเอง

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

ปรับปรุง ในส่วนที่เกี่ยวข้องกับตัวอย่างของคุณนี้น่าจะเหมาะสมกว่า:

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

4
brilliant SO, ไม่อนุญาตให้แก้ไขการi/elseพิมพ์ผิดเนื่องจากมีอักขระไม่เพียงพอ
น้ำค้าง

1
เป็นโมฆะ (เงื่อนไข && x = จริง) - ดูดี แต่ดูเหมือนจะผิดพลาด "การมอบหมายที่ไม่ถูกต้องด้านซ้ายมือ" ข้อผิดพลาด
Eugene Tiurin

1
เป็นโมฆะ (เงื่อนไข && (x = จริง)) // แยกการกำหนดจากค่าแรก
diamondsea

4
อย่างไรก็ตามสิ่งนี้ไม่ง่ายต่อการอ่านโดยเฉพาะอย่างยิ่งสำหรับนักพัฒนาที่ไม่คุ้นเคยกับสไตล์นี้ คุณสามารถเขียนได้อย่างง่ายดายและอ่านได้ง่ายขึ้นเช่น: if (condition) {x = true; }
diamondsea

2
คุณช่วยอธิบายว่า "ไม่ผ่านการตรวจสอบ" หมายความว่าอย่างไร void()ผมไม่เข้าใจว่าทำไมหนึ่งควรห่อแสดงออกใน ขอบคุณ
gilad mayani

20

ไม่มันต้องการตัวถูกดำเนินการสามตัว นั่นเป็นเหตุผลที่พวกเขาเรียกว่าประกอบไปด้วยผู้ประกอบการที่

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

if(condition) x = true;

แม้ว่าการจัดฟันจะปลอดภัยกว่าหากคุณต้องการเพิ่มคำสั่งมากกว่าหนึ่งคำในอนาคต:

if(condition) { x = true; }

แก้ไข:ตอนนี้คุณพูดถึงรหัสจริงที่ใช้กับคำถามของคุณ:

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

1
คุณทำได้ แต่ไม่ควร อย่างน้อยไม่ได้โดยไม่ต้องวงเล็บปีกการอบ - มันผิดพลาดมาก
Konerak

1
มันเป็นเรื่องจริงเหรอ? ฉันเข้าใจเหตุผลหลักที่ต้องการการรักษาเนื่องจากพวกเขาทำให้ชีวิตของ jslint ง่ายขึ้น
Cheeso

@Cheeso มันเป็นข้อผิดพลาดในแง่ของการปรับโครงสร้าง คุณกลับมาเพื่อเพิ่มสิ่งที่ต้องทำเพิ่มเติมในกรณีที่มีสภาพที่แท้จริงโดยไม่ทราบว่าไม่มีวงเล็บปีกกาที่นั่น รหัสใหม่จะดำเนินการเสมอแทนที่จะเป็นกรณีเมื่อจริง
Matt S

ไม่ฉันรู้ว่าฉันชอบเขียนเงื่อนไขโดยไม่มีความพิเศษเช่นถ้า () {} else {} เมื่อมันเท่ากับหรือไม่?:;
ออสการ์ Godson

3
สุจริตฉันไม่เคยรู้จักนักพัฒนากลัวการใช้ภาษามากกว่า Javascript: -PI ไม่อยากให้มีคนบอกฉันว่าฉันไม่ควรใช้เครื่องมือจัดฟันแบบหยิก ฉันละเว้นพวกเขามากและไม่เคยมีปัญหาใด ๆ มากกว่าที่ฉันจะพลาดรั้ง
Andy E

12

บ่อยครั้งที่ผู้คนใช้ประโยชน์จากตัวดำเนินการเชิงตรรกะเพื่อย่นไวยากรณ์คำสั่งให้สั้นลง:

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

แต่ในกรณีของคุณไวยากรณ์อาจง่ายกว่านี้

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

รหัสนี้จะส่งคืนdefaults.slideshowWidthค่าถ้าdefaults.slideshowWidthประเมินเป็นจริงและobj.find('img').width()+'px'คุ้มค่าเป็นอย่างอื่น

ดูการประเมินการลัดวงจรของตัวดำเนินการเชิงตรรกะสำหรับรายละเอียด


11
var x = condition || null;

2
(defaults.slideshowWidth) || (defaults.slideshowWidth = obj.find('img').width()+'px')หรือdefaults.slideshowWidth = defaults.slideshowWidth || (obj.find('img').width()+'px')
Casey Chu

> ส่งคืน expr1 หากสามารถแปลงเป็นจริงได้ มิฉะนั้นส่งคืน expr2 ผู้ให้บริการลอจิคัล (MDN)
Szabolcs Páll

5

คุณสามารถเขียน

x = condition ? true : x;

ดังนั้น x จะไม่ถูกแก้ไขเมื่อเงื่อนไขเป็นเท็จ

สิ่งนี้จะเทียบเท่ากับ

if (condition) x = true

แก้ไข:

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

มีทางเลือกสองทางคือ - ฉันไม่ได้บอกว่าสิ่งเหล่านี้ดีกว่าหรือแย่กว่า - ทางเลือกอื่น

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

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

ปลอดภัยกว่า แต่อาจดูไม่ดีและพิมพ์ได้มากกว่านี้ ในทางปฏิบัติฉันอาจจะเขียน

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

บางรหัสสดคือ (ยังไงก็ตามเพื่อกำจัด null ในนี้?):! defaults.slideshowWidth? defaults.slideshowWidth = obj.find ('img'). width () + 'px': null;
ออสการ์ Godson

2

ในกรณีของคุณฉันเห็นผู้ประกอบการที่สามเป็นซ้ำซ้อน คุณสามารถกำหนดตัวแปรให้กับนิพจน์โดยตรงโดยใช้ ||, && โอเปอเรเตอร์

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

จะกลายเป็น :

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

ชัดเจนยิ่งขึ้นเป็นสไตล์ "javascript" มากขึ้น



1

ในการใช้ผู้ประกอบการ Ternary โดยไม่มีอย่างอื่นในอาร์เรย์หรือการประกาศวัตถุคุณสามารถใช้ตัวดำเนินการแพร่กระจาย ES6 ...()

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

และสำหรับวัตถุ:

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

แหล่งต้นฉบับ

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