ฉันเจอบทความนี้อธิบายการตอบคำถาม JavaScript Quiz-Legend อย่างไรก็ตามมันก็โอเคดังนั้นฉันต้องการนำมาที่นี่เพื่อให้ทุกคนเรียนรู้เข้าใจท่องและวิพากษ์วิจารณ์
คำถามที่ 1
(function () {return typeof arguments; // "object"}) ();อาร์กิวเมนต์เป็นวัตถุคล้ายอาร์เรย์ซึ่งสอดคล้องกับรายการพารามิเตอร์ของฟังก์ชันที่ผ่าน คุณสามารถใช้ตัวแปรนี้ได้โดยตรงในฟังก์ชั่นใด ๆ
ตัวดำเนินการ typeof จะส่งคืนผลลัพธ์ของสตริงประเภทเท่านั้น อ้างถึงรายการต่อไปนี้เพื่อทราบว่าค่าที่ส่งคืนโดย typeof คือข้อมูลที่แตกต่างกันที่สอดคล้องกันอย่างไร:
จากนี้เราอนุมานได้ว่าอาร์กิวเมนต์ประเภทนั้นเป็นวัตถุ
คำถามที่ 2
var f = ฟังก์ชั่น g () {return 23; }; typeof g (); // รายงานข้อผิดพลาดนี่คือนิพจน์ฟังก์ชั่นที่มีชื่อ G และจากนั้นจะถูกกำหนดให้กับตัวแปร F
ชื่อฟังก์ชั่น G ที่นี่และตัวแปร F ที่กำหนดโดยมันมีความแตกต่างต่อไปนี้:
ชื่อฟังก์ชันไม่สามารถเปลี่ยนแปลงได้ในขณะที่ตัวแปร F สามารถกำหนดใหม่ได้
ชื่อฟังก์ชั่นสามารถใช้งานได้ภายในตัวถังฟังก์ชั่นเท่านั้น หากคุณพยายามใช้ G นอกฟังก์ชั่นจะมีการรายงานข้อผิดพลาด
คำถามที่ 3
(ฟังก์ชั่น (x) {ลบ x; return x; // 1}) (1);ตัวดำเนินการลบสามารถลบแอตทริบิวต์ออกจากวัตถุและการใช้งานที่ถูกต้องมีดังนี้:
ลบ object.property
ลบวัตถุ ['คุณสมบัติ']
ตัวดำเนินการลบสามารถใช้กับคุณสมบัติของวัตถุเท่านั้นและไม่ถูกต้องสำหรับตัวแปรและชื่อฟังก์ชัน กล่าวคือลบ X ไม่มีความหมาย
คุณควรทราบดีกว่าว่าการลบจะไม่ปล่อยหน่วยความจำโดยตรง แต่เพียงแค่ขัดจังหวะการอ้างอิงวัตถุทางอ้อม
คำถามที่ 4
var y = 1, x = y = typeof x; x; // "ไม่ได้กำหนด"
เราพยายามแยกรหัสด้านบนออกเป็นสองขั้นตอนต่อไปนี้:
var y = 1; // ขั้นตอนที่ 1
var x = y = typeof x; // ขั้นตอนที่ 2
ไม่ควรคัดค้านขั้นตอนแรกลองดูขั้นตอนที่สองโดยตรง
1. การแสดงออกที่ได้รับมอบหมายจะดำเนินการจากขวาไปซ้าย
2. ผลลัพธ์ของการได้รับการกำหนดใหม่ให้กับ typeof x นั่นคือ undefined
3.x ถูกกำหนดให้เป็นผลมาจากนิพจน์ที่ถูกต้อง (y = typeof x) นั่นคือไม่ได้กำหนด
คำถามที่ 5
(ฟังก์ชั่น f (f) {return typeof f (); // "number"}) (function () {return 1;});ความคิดเห็นโดยตรงคำอธิบาย:
(ฟังก์ชั่น f (f) {// f นี่คือพารามิเตอร์ที่ส่งผ่านในฟังก์ชัน () {return 1;} // ผลลัพธ์ของการดำเนินการตามธรรมชาติ 1 ส่งคืน typeof f (); // ดังนั้นตามตารางในคำถามหนึ่งเรารู้ว่า typeof 1 ผลลัพธ์คือ "number"})คำถามที่ 6
var foo = {bar: function () {return this.baz; }, baz: 1}; (function () {return typeof อาร์กิวเมนต์ [0] (); // "undefined"}) (foo.bar);ที่นี่คุณอาจคิดผิดพลาดว่าผลลัพธ์สุดท้ายคือจำนวน พารามิเตอร์การส่งผ่านไปยังฟังก์ชันสามารถถือได้ว่าเป็นการกำหนดดังนั้นอาร์กิวเมนต์ [0] ได้รับค่าของฟังก์ชันแถบจริงแทนที่จะอ้างอิงถึง foo.bar ดังนั้นโดยธรรมชาติแล้วสิ่งนี้จะไม่ชี้ไปที่ foo แต่หน้าต่าง
คำถามที่ 7
var foo = {bar: function () {return this.baz; }, baz: 1} typeof (f = foo.bar) (); // "ไม่ได้กำหนด"นี่เป็นปัญหาเดียวกับคำถามก่อนหน้า (f = foo.bar) ส่งคืนค่าของบาร์ไม่ใช่การอ้างอิงดังนั้นสิ่งนี้ไม่ได้อ้างถึง Foo
คำถามที่ 8
var f = (ฟังก์ชั่น f () {return '1';}, ฟังก์ชัน g () {return 2;}) (); typeof f; // "หมายเลข"ตัวดำเนินการเครื่องหมายจุลภาคประเมินวัตถุการดำเนินการแต่ละรายการ (จากซ้ายไปขวา) และส่งคืนค่าของวัตถุการดำเนินการสุดท้าย
ดังนั้นค่าส่งคืนของ (ฟังก์ชัน f () {return '1';}, ฟังก์ชัน g () {return 2;}) คือฟังก์ชัน g จากนั้นเรียกใช้งานแล้วผลลัพธ์คือ 2; ในที่สุด Typeof 2 ตามตารางที่เป็นปัญหาหนึ่งผลลัพธ์คือจำนวนตามธรรมชาติ
คำถามที่ 9
var x = 1; ถ้า (ฟังก์ชัน f () {}) {x += typeof f;} x; // "1UndEfined"จุดสำคัญของปัญหานี้เรากล่าวถึงในคำถามที่ 2 ชื่อฟังก์ชั่น F ในนิพจน์ฟังก์ชั่นไม่สามารถเข้าถึงได้นอกร่างกายฟังก์ชั่น
คำถามที่ 10
var x = [typeof x, typeof y] [1]; typeof typeof x; // "string" 1. เนื่องจากตัวแปร y ยังไม่ได้รับการประกาศ, typeof y กลับ "undefined"
2. กำหนดผลลัพธ์ของประเภท y ถึง x นั่นคือ x ตอนนี้ "ไม่ได้กำหนด"
3. Typeof X คือ "String" แน่นอน
4. ผลลัพธ์สุดท้ายของ typeof "สตริง" ยังคงเป็น "สตริง" ตามธรรมชาติโดยธรรมชาติ
คำถามที่ 11
(ฟังก์ชั่น (foo) {return typeof foo.bar; // "undefined"}) ({foo: {bar: 1}});นี่เป็นเคล็ดลับภาพที่บริสุทธิ์แสดงความคิดเห็น
(ฟังก์ชั่น (foo) {// foo นี่คือ {foo: {bar: 1}} และไม่มีแอตทริบิวต์บาร์ // แอตทริบิวต์บาร์อยู่ด้านล่าง foo.foo//o ผลลัพธ์ที่นี่คือคำถามที่ 12
(ฟังก์ชั่น f () {function f () {return 1;} return f (); // 2 function f () {return 2;}}) ();ฟังก์ชั่นที่ประกาศผ่านการประกาศฟังก์ชั่นสามารถใช้ก่อนการประกาศซึ่งเราเรียกว่าคุณลักษณะนี้ยกขึ้น ดังนั้นรหัสข้างต้นจึงอธิบายได้จริงโดยสภาพแวดล้อมที่กำลังดำเนินอยู่เช่นนี้:
(ฟังก์ชั่น f () {function f () {return 1;} function f () {return 2;} return f ();}) ();คำถามที่ 13
ฟังก์ชั่น f () {return f; } ใหม่ f () อินสแตนซ์ของ f; // falseเมื่อรหัสใหม่ F () ดำเนินการสิ่งต่อไปนี้จะเกิดขึ้น:
1. วัตถุใหม่ถูกสร้างขึ้น มันสืบทอดมาจาก f.prototype
2. ตัวสร้าง F ถูกดำเนินการ ในระหว่างการดำเนินการผ่านที่สอดคล้องกันจะถูกส่งผ่านและบริบท (นี้) จะถูกระบุเป็นอินสแตนซ์ใหม่นี้ F ใหม่เทียบเท่ากับ F () ใหม่และสามารถใช้ได้เฉพาะในกรณีที่ไม่มีการส่งพารามิเตอร์
3. หากคอนสตรัคเตอร์ส่งคืน "วัตถุ" วัตถุนี้จะแทนที่ผลลัพธ์ของใหม่ทั้งหมด หากตัวสร้างไม่ส่งคืนวัตถุผลลัพธ์ของใหม่คือวัตถุที่สร้างขึ้นในขั้นตอนที่ 1
PS: ภายใต้สถานการณ์ปกติตัวสร้างจะไม่ส่งคืนค่าใด ๆ แต่ถ้าผู้ใช้ต้องการเขียนทับค่าคืนนี้เขาสามารถเลือกที่จะส่งคืนวัตถุปกติเพื่อเขียนทับ แน่นอนว่าอาร์เรย์ที่ส่งคืนจะถูกเขียนทับเพราะอาร์เรย์เป็นวัตถุเช่นกัน
ดังนั้น F () ใหม่เราที่นี่ยังคงส่งคืนฟังก์ชัน F ตัวเองไม่ใช่อินสแตนซ์ของมัน
คำถามที่ 14
ด้วย (ฟังก์ชั่น (x, ไม่ได้กำหนด) {}) ความยาว; // 2
คำสั่งด้วยเพิ่มวัตถุที่ด้านบนของห่วงโซ่ขอบเขต หากมีตัวแปรที่ไม่ได้ใช้เนมสเปซในคำสั่งซึ่งมีชื่อเดียวกันกับคุณสมบัติในห่วงโซ่ขอบเขตตัวแปรจะชี้ไปที่ค่าคุณสมบัติ หากมีคุณสมบัติที่มีชื่อเดียวกันจะมีข้อยกเว้น ReferenceRoror
ตกลงตอนนี้ลองดูที่ฟังก์ชั่น (x, undefined) {} เป็นนิพจน์ฟังก์ชันที่ไม่ระบุชื่อซึ่งเป็นฟังก์ชั่นมันจะมีแอตทริบิวต์ความยาวซึ่งหมายถึงจำนวนพารามิเตอร์ของฟังก์ชัน ดังนั้นผลลัพธ์สุดท้ายคือ 2
เขียนในตอนท้าย
บางคนคิดว่าคำถามเหล่านี้ยุ่งยากในขณะที่คนอื่นคิดว่ามันขยายขอบเขตอันไกลโพ้นและขึ้นอยู่กับความคิดเห็นของตนเอง แต่สิ่งหนึ่งคือความจริง ไม่ว่าคุณจะเป็นผู้ปฏิบัติงานที่มั่นคงหรือไม่คุณจะไม่ไปไกลโดยไม่มีรากฐานทางทฤษฎี - คุณจะไม่เห็นพนักงานด้านเทคนิคที่มีทักษะใด ๆ กลายเป็นผู้เชี่ยวชาญด้านจรวด
การอ่านเอกสารมาตรฐานการอ่านและการรวมการฝึกฝนเป็นวิธีที่เด็ดขาดสำหรับสหาย
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น