ฉันสังเกตเห็นในวันนี้ว่า Chrome 49 จะไม่แสดงผลอีกต่อไปNaNเมื่อคุณพิมพ์{}+{}ลงในคอนโซล [object Object][object Object]แต่มันจะออกผลลัพธ์สตริง
ทำไมนี้ ภาษาเปลี่ยนไปหรือไม่?
ฉันสังเกตเห็นในวันนี้ว่า Chrome 49 จะไม่แสดงผลอีกต่อไปNaNเมื่อคุณพิมพ์{}+{}ลงในคอนโซล [object Object][object Object]แต่มันจะออกผลลัพธ์สตริง
ทำไมนี้ ภาษาเปลี่ยนไปหรือไม่?
คำตอบ:
ตอนนี้ Chrome devtools จะห่อทุกอย่างที่ขึ้นต้นด้วย{และลงท้ายด้วย}วงเล็บโดยปริยายคู่ ( ดูรหัส ) เพื่อบังคับให้การประเมินผลเป็นนิพจน์ ด้วยวิธีนี้{}สร้างวัตถุว่างเปล่าในขณะนี้ คุณสามารถดูนี้ถ้าคุณกลับไปถึงประวัติศาสตร์ ( ↑) (…)บรรทัดก่อนหน้าจะถูกบรรจุอยู่ใน
ทำไม? ฉันไม่รู้ แต่ฉันเดาได้ว่ามันช่วยลดความสับสนสำหรับมือใหม่ที่ไม่รู้เรื่องของตัวบล็อกและวัตถุและมันก็มีประโยชน์มากขึ้นถ้าคุณต้องการประเมินการแสดงออก
และในความเป็นจริงนั่นคือเหตุผลที่กล่าวไว้ในข้อผิดพลาด 499864 สะดวกสบายอย่างแท้จริง และเนื่องจากโหนด REPL ก็มีเช่นกัน ( ดูรหัส )
{a:1}),({b:2}ควรเกิดข้อผิดพลาดไม่ใช่สร้างวัตถุ
)ในกรณีที่มันอยู่ในความคิดเห็นเช่น{a:3} // :-}อาจยังคงผลิตวัตถุ
ถ้าคุณกดลูกศรขึ้นหลังจากการตรวจสอบนี้คุณจะสังเกตเห็นว่าแทน{} + {}มันแสดงซึ่งผลในการ({} + {})"[object Object][object Object]"
ในการเปรียบเทียบใน Firefox {} + {}จะยังคงปรากฏNaNแต่ถ้าคุณทำ({} + {})มันก็จะปรากฏ"[object Object][object Object]"ขึ้น
ดังนั้นดูเหมือนว่า Chrome จะเพิ่มวงเล็บล้อมรอบโดยอัตโนมัติเมื่อเห็นการดำเนินการนี้
{} + {}เมื่อไม่ "ทำความสะอาด" ให้({} + {})ถือว่าเป็น+ {}เพราะ{}ถูกแยกวิเคราะห์เป็นบล็อกว่างเปล่า
{}นั้นเป็นเพียงแค่โค้ดบล็อกว่างเปล่าและไม่สนใจปล่อยให้เรา+{}ซึ่งเป็น+วัตถุที่ไม่มีค่าและว่างเปล่า การเริ่มต้น +จะบีบบังคับอาร์กิวเมนต์ให้เป็นตัวเลขซึ่งเกี่ยวข้องกับการแปลงวัตถุให้เป็นแบบดั้งเดิม (ซึ่งจะจบลงด้วยการเป็นtoStringในกรณีนี้ส่งผลให้"[object Object]") และดังนั้นเราจึงได้รับ+"[object Object]"ซึ่งเป็นNaNเพราะ"[object Object]"ไม่สามารถแปลงเป็นจำนวนที่ถูกต้อง
น่าเสียดายที่ฉันเพิ่ม Clippy พูดด้วยตัวเอง คอนโซลไม่ให้ข้อมูลเกี่ยวกับสิ่งที่ทำเพื่อคุณ
กฎใหม่นั้นเรียบง่ายอย่างไม่น่าเชื่อช่วยให้เราสามารถพิมพ์ตัวอักษรสองตัวที่ยากลำบากเหล่านี้o=หรือ0,ก่อนที่จะวาง Object Objectals ลงในคอนโซล:
{;{wat:1}),({wat:2} ในที่สุดก็เป็นข้อผิดพลาดอีกครั้ง
{let i=0;var increment=_=>i++} ได้รับอนุญาตอย่างถูกต้องในที่สุดซึ่งเป็นวิธีที่ดีในการทำปิด
อย่างไรก็ตามสิ่งต่อไปนี้เป็นวัตถุที่ไม่ถูกต้องนี่เป็นเพียงความสะดวกสบายตามที่ระบุไว้โดย @Bergi ซึ่งตีความ JS ผิดเพื่อช่วยคุณ! ข้อมูลจำเพาะบอกว่ามันเป็นบล็อกที่มีข้อความกำกับ "foo" ที่มีตัวอักษร 1 ที่ไม่ได้กำหนดให้กับอะไร
{foo:1}
ข้างต้นควรเป็นเช่นเดียวกับ
if(1) {
foo: 1
}
ต่อไปนี้จะถือว่าเป็นบล็อกอย่างถูกต้อง ... เนื่องจากมีความคิดเห็นอยู่ข้างหน้า!
//magic comment
{foo:1}
ดังนั้นนี่คือ:
{foo:1}
//also magic
นี่คือวัตถุ:
{foo:
//not so magic comment
1}
นี่เป็นข้อผิดพลาด
//not so magic comment
{foo:1}.foo
ดังนั้นนี่คือ:
{foo:1}.foo
นี่เป็นเรื่องปกติ:
1..wat
undefined
ดังนั้นนี่คือ:
['foo'][0]
สิ่งต่อไปนี้ถูกตีความอย่างถูกต้องว่าเป็นวัตถุที่ตีเข้าไปในตำแหน่งนิพจน์0,ซึ่งโดยทั่วไปแล้วเรามั่นใจได้อย่างชัดเจนว่าเรามีการแสดงออกแทนที่จะเป็นคำสั่ง
0,{foo:1}.foo
ฉันไม่เข้าใจว่าทำไมพวกเขาถึงห่อค่าในการล้อ JS มีการตัดสินใจการออกแบบที่ไร้สาระ แต่การพยายามทำให้มันดีกว่าในสถานการณ์นี้ไม่ใช่ตัวเลือกจริงๆคอนโซลจำเป็นต้องรัน JS อย่างถูกต้องและเราต้องมั่นใจว่า Chrome ไม่ได้คาดเดาว่าเราคิดว่าเราคิด จริงๆหมายถึงมันจะทำอย่างอื่น
หากคุณไม่ชอบเครื่องหมายจุลภาคคุณสามารถใช้การมอบหมาย
x = {foo:1}.foo
เพราะอย่างที่มันยืน
{} + {} + {}
"[object Object][object Object][object Object]"
;{} + {} + {}
"NaN[object Object]"
บ้าและสอดคล้องฉันสามารถจัดการกับ ... บ้าและไม่สอดคล้องไม่ขอบคุณ!
{foo:1}และ{foo:1}//ผลิตสิ่งเดียวกัน ใน Chrome JS REPL พวกเขาทำไม่ได้ REPL กำลังทำมากกว่าการประเมิน JS มันกำลังประมวลผลสตริงและตัดสินใจไปยังสิ่งต่าง ๆ
var x = eval('{a:1}')ใน JavaScript x ที่ถูกต้องคือตอนนี้ 1 ไม่ใช่วัตถุที่ใช้งานง่ายกว่า {a: 1} ใช่มันแปลก แต่คุณไม่สามารถเปลี่ยนภาษาได้เพราะมันทำสิ่งแปลก ๆ ทุกอย่างนอกเหนือจากสตริง JSON จะถูกตีความเป็น JavaScript และประเมินผล การพิมพ์0,ก่อนวาง JSON นั้นไม่ใช่เรื่องยากอีกทางหนึ่งฉันยินดีที่จะเตือนว่าสตริงถูกตีความว่าเป็นวัตถุแทนที่จะเป็น JavaScript เพื่อความสะดวก
var e = {}; e.toString()แล้วคุณจะเห็นว่าฉันหมายถึงอะไร