คอมมาทำอะไรในนิพจน์ JavaScript?


89

ถ้าฉันใช้:

1.09 * 1; // returns "1.09"

แต่ถ้าฉันใช้:

1,09 * 1; // returns "9"

ฉันรู้ว่า 1,09 ไม่ใช่ตัวเลข

ลูกน้ำทำอะไรในโค้ดชิ้นสุดท้าย

ตัวอย่างเพิ่มเติม

if (0,9) alert("ok"); // alert
if (9,0) alert("ok"); // don't alert

alert(1); alert(2); alert(3); // 3 alerts
alert(1), alert(2), alert(3); // 3 alerts too

alert("2",
    foo = function (param) {
        alert(param)
    },
    foo('1')
)
foo('3'); // alerts 1, 2 and 3

1
ฉันประหลาดใจที่ 09 ไม่ล้มเหลวสำหรับ '9' ที่ผิดกฎหมายในตัวอักษรฐานแปด
ออกอากาศซ้ำ

7
@recursive - 9 ใด ๆ ในการแทนค่าฐานแปดจะส่งผลให้ทางเลือกกลับเป็นทศนิยม
Yuval Adam

อย่าสับสนระหว่างจุลภาคในรายการอาร์กิวเมนต์ alertใช้อาร์กิวเมนต์เดียวเท่านั้น สิ่งใดก็ตามหลังจากนั้นจะถูกทิ้ง
แอนดรูว์

@ แอนดรูว์: ใช่ถูกยกเลิกโดย alert () ซึ่งใช้อาร์กิวเมนต์เดียวเท่านั้น แต่จะถูกเรียกใช้! แปลก. ขอบคุณ.
Topera

1
@Topera: ไม่แปลกจริงๆถ้าคุณคิดจากมุมมองของ JS ใน JS คุณไม่จำเป็นต้องระบุรายการอาร์กิวเมนต์ของคุณในการประกาศฟังก์ชันของคุณ (คุณสามารถใช้argumentsออบเจ็กต์แทนซึ่งอาจมีความยาวเท่าใดก็ได้) แม้จะใช้ JS ที่คอมไพล์แล้วก็ไม่มีทางที่จะบอกล่วงหน้าได้ว่าฟังก์ชันจะต้องใช้อาร์กิวเมนต์กี่ข้อ พิจารณาสิ่งนี้: function test() { args=[]; for (var i = 0; i < arguments.length; i++) { args.push(arguments[i] + 1); } ;ล่ามจะต้องรู้ว่าฟังก์ชันถูกใช้อย่างไรจึงจะรู้ว่าต้องใช้อาร์กิวเมนต์กี่ตัว แต่จะประเมินทุกอย่างแทน
แอนดรูว์

คำตอบ:


95

ตัวดำเนินการลูกน้ำจะประเมินตัวถูกดำเนินการทั้งสอง (จากซ้ายไปขวา) และส่งคืนค่าของตัวถูกดำเนินการที่สอง

ที่มา: https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special_Operators/Comma_Operator

ยกตัวอย่างเช่นการแสดงออกประเมิน1,2,3,4,5 5เห็นได้ชัดว่าตัวดำเนินการลูกน้ำมีประโยชน์สำหรับการดำเนินการที่มีผลข้างเคียงเท่านั้น

console.log(1,2,3,4,5);
console.log((1,2,3,4,5));


2
พวกเขาเอามาจาก C. ฉันคิดว่ามันมีประโยชน์สำหรับการแสดงออกที่มีผลข้างเคียงเท่านั้น
Radomir Dopieralski

3
ฉันไม่สามารถนึกถึงหลาย ๆ กรณีที่ตัวดำเนินการลูกน้ำถูกใช้เพื่อส่งผลกระทบใด ๆ แต่เป็นการประหยัดอักขระ (การย่อขนาด) หรือรหัสที่ทำให้สับสน
user17753

1
@ user17753 สามารถใช้ได้อย่างถูกต้องในส่วนที่คั่นด้วยอัฒภาคของforลูป
Cyoce

1
@Cyoce: แม้ว่าจะเป็นเรื่องจริง แต่การพูดโดยทั่วไปตรรกะดังกล่าวทำได้ชัดเจนกว่าในเนื้อหาของวง จากนั้นบางคนจะอ้างว่าทางของพวกเขาอนุญาตให้มีหลายcontinueจุดโดยไม่ซ้ำซ้อน แต่คุณไม่ควรมีหลายcontinueจุด
Lightness Races ในวงโคจร

@ user17753 คุณมีเงิน; การพยายามทำความเข้าใจโค้ดย่อขนาดเล็กคือสาเหตุที่ฉันมาที่นี่
ไม่ค่อย 'Where's Monica' Needy

6

สิ่งที่ควรพิจารณาเพิ่มเติม:

console.log((0, 9));
console.log((9, 0));
console.log(("foo", "bar"));


7
ฮ่า ๆ มันสนุกดี:alert("1", alert("2", alert("3")))
Topera

1
@ แอนดรูว์: อ๊ะฉันได้อัปเดตคำตอบของฉันด้วยสิ่งที่ฉันตั้งใจจะใช้
ดักลาส

ตัวดำเนินการลูกน้ำจะประเมินตัวถูกดำเนินการแต่ละตัว (จากซ้ายไปขวา) และส่งคืนค่าของlastตัวถูกดำเนินการ
xgqfrms

2
ตัวดำเนินการลูกน้ำจะประเมินตัวถูกดำเนินการทั้งสอง (จากซ้ายไปขวา) และส่งกลับค่าของsecond ตัวถูกดำเนินการ

https://stackoverflow.com/a/3561056/5934465

มันควรจะเป็นแบบนี้!

ตัวดำเนินการลูกน้ำจะประเมินแต่ละตัวถูกดำเนินการ (จากซ้ายไปขวา) และส่งคืนค่าของlastตัวถูกดำเนินการ

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator


5
ตัวดำเนินการลูกน้ำใช้ตัวถูกดำเนินการสองตัวดังนั้นคำพูดเดิมจึงถูกต้อง สิ่งที่คุณกำลังพูดถึงคือผลลัพธ์สุดท้ายของการซ้อนนิพจน์ดังกล่าว แต่หมายความว่าใบเสนอราคาแทนที่ของคุณมีคำที่ผิดอย่างละเอียด a,b,c,dคือ((((a),b),c),d)
Lightness Races ในวงโคจร

1

ดูที่นี่ - เครื่องหมายจุลภาคหมายถึงหลายนิพจน์ / คำสั่ง ตัวอย่างเช่นในรหัสของคุณคุณสามารถใช้บรรทัดดังนี้:

var a=0, b=0, c=0;

สิ่งนี้จะประกาศตัวแปรทั้งสามโดยไม่ต้องเขียน:

var a=0;
var b=0;
var c=0;

หวังว่าจะช่วยได้


23
เก่าไปหน่อย แต่สิ่งสำคัญที่ควรทราบ: (1) ตัวอย่างที่คุณให้ไว้ไม่ได้ใช้ตัวดำเนินการลูกน้ำ ( varการประกาศไม่ใช้ตัวดำเนินการลูกน้ำแม้ว่าจะเป็นเครื่องหมายจุลภาค) และ (2) คุณไม่สามารถแยกได้ สถิติโดยใช้ตัวดำเนินการลูกน้ำ อนุญาตเฉพาะนิพจน์เท่านั้น
Qantas 94 Heavy

0

การเพิ่ม / แก้ไขคุณสมบัติให้กับวัตถุและส่งคืนในบรรทัดเดียวกันเป็นกรณีการใช้งานที่เป็นไปได้:

console.log(
  ((x) => (o = {biggerCond: r => r >= x},
           o.r5 = Array.from(window.crypto.getRandomValues(new Uint16Array(5))),
           o.isAnyBigger = o.r5.some(o.biggerCond),
           o.bigger = o.isAnyBigger ? o.r5.filter(o.biggerCond) : [x], o )
  )(5e4)
);
// Example
// {
//   bigger: [58414, 56500, 63397],
//   isAnyBigger: true,
//   isBiggerCond: r => r >= x,
//   r5: [58414, 12015, 56500, 63397, 43861]
// }

ฟังก์ชันที่ไม่ระบุตัวตนข้างต้นจะส่งคืนอ็อบเจ็กต์ที่มีค่าสุ่มที่ใหญ่กว่าค่าอินพุตหรือหากไม่มีค่าอินพุตในอาร์เรย์ที่อยู่ในbiggerคุณสมบัติ

มันยังคงเป็นน้ำตาลที่เป็นประโยค (เช่นฟังก์ชันลูกศร ) แต่มันทำให้จำนวนบรรทัดสั้นลง ... ฉันสงสัยว่าตัวย่อ JS บางตัวตรวจจับและปรับโค้ดในลักษณะเดียวกันโดยอัตโนมัติ เรียกใช้ในคอนโซลของคุณ:

((x)=>(o={biggerCond:r=>r>=x},o.r5=Array.from(window.crypto.getRandomValues(new Uint16Array(5))),o.isAnyBigger=o.r5.some(o.biggerCond),o.bigger=o.isAnyBigger?o.r5.filter(o.biggerCond):[x],o))(5e4)

2
แต่แน่นอนว่าคุณจะไม่ใส่คาถาที่คลุมเครือเช่นนี้ลงในรหัสการผลิตใช่ไหม?
Lightness Races ในวงโคจร

@LightnessRacesinOrbit ดีฉันจะบอกว่ามันขึ้นอยู่กับวัตถุประสงค์ (เช่นการสอนการย่อรหัสไม่มีการประกาศตัวแปร / ฟังก์ชัน ฯลฯ ) ถ้าคุณเยื้องตามที่ฉันทำไว้ข้างต้นมันอ่านได้อย่างสมบูรณ์ ... หยุดสังเกตไม่ได้ว่าคุณใช้คำว่า "คลุมเครือ" :)
CPHPython

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